Prevent calling function pointers cast to an incompatible type.

Most often, this had happened when casting comparison functions for qsort()
like these: "int yax_cmpbunches(const int16_t *b1, const int16_t *b2)"
to a function pointer type expecting "const void *". Alas, this is undefined
behavior: see
http://blog.frama-c.com/index.php?post/2013/08/24/Function-pointers-in-C
and posts linked from it.

At least two cases have not been fixed:
- The savegame system maintains pointers which are either to data or a function in
  the generic "void *". This ought to be made into a union.
- Probably also:
  #define OSD_ALIAS     (int32_t (*)(const osdfuncparm_t*))0x1337

git-svn-id: https://svn.eduke32.com/eduke32@4068 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-09-21 13:38:44 +00:00
parent d2cd8af510
commit 514a3bfd64
8 changed files with 44 additions and 39 deletions

View file

@ -214,9 +214,9 @@ void fade_editor_screen(int32_t keepcol);
extern int32_t getnumber_internal1(char ch, int32_t *danumptr, int32_t maxnumber, char sign);
extern int32_t getnumber_autocomplete(const char *namestart, char ch, int32_t *danum, int32_t flags);
int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t));
int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t));
#define getnumber256(namestart, num, maxnumber, sign) _getnumber256(namestart, num, maxnumber, sign, NULL)
int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t));
int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t));
#define getnumber16(namestart, num, maxnumber, sign) _getnumber16(namestart, num, maxnumber, sign, NULL)
void printmessage256(int32_t x, int32_t y, const char *name);
void message(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));

View file

@ -2595,10 +2595,10 @@ static int32_t sectors_components(int16_t hlsectcnt, const int16_t *hlsector, in
return 2;
}
static int cmpgeomwal1(const int16_t *w1, const int16_t *w2)
static int cmpgeomwal1(const void *w1, const void *w2)
{
const walltype *wal1 = &wall[*w1];
const walltype *wal2 = &wall[*w2];
const walltype *wal1 = &wall[*(int16_t *)w1];
const walltype *wal2 = &wall[*(int16_t *)w2];
if (wal1->x == wal2->x)
return wal1->y - wal2->y;
@ -2608,7 +2608,7 @@ static int cmpgeomwal1(const int16_t *w1, const int16_t *w2)
static void sort_walls_geometrically(int16_t *wallist, int32_t nwalls)
{
qsort(wallist, nwalls, sizeof(int16_t), (int(*)(const void *, const void *))&cmpgeomwal1);
qsort(wallist, nwalls, sizeof(int16_t), &cmpgeomwal1);
}
#endif
@ -8946,7 +8946,7 @@ int32_t getnumber_autocomplete(const char *namestart, char ch, int32_t *danum, i
// 2: autocomplete names
// 4: autocomplete taglabels
// 8: return -1 if cancelled
int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t))
int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t))
{
char buffer[80], ournamestart[80-17], ch;
int32_t n, danum, oldnum;
@ -8978,7 +8978,7 @@ int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char
if (func != NULL)
{
Bsnprintf(buffer, sizeof(buffer), "%s", (char *)func(danum));
Bsnprintf(buffer, sizeof(buffer), "%s", func(danum));
// printext16(200L-24, ydim-STATUS2DSIZ+20L, editorcolors[9], editorcolors[0], buffer, 0);
printext16(n<<3, ydim-STATUS2DSIZ+128, editorcolors[11], -1, buffer,0);
}
@ -9017,7 +9017,7 @@ static void getnumber_clearline(void)
}
// sign: |16: don't draw scene
int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, void *(func)(int32_t))
int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, char sign, const char *(func)(int32_t))
{
char buffer[80], ournamestart[80-13], ch;
int32_t danum, oldnum;
@ -9062,7 +9062,7 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
printmessage256(0, 0, buffer);
if (func != NULL)
{
Bsnprintf(buffer, sizeof(buffer), "%s", (char *)func(danum));
Bsnprintf(buffer, sizeof(buffer), "%s", func(danum));
printmessage256(0, 9, buffer);
}

View file

@ -785,9 +785,9 @@ static void yax_scanbunches(int32_t bbeg, int32_t numhere, const uint8_t *lastgo
scansector_retfast = 0;
}
static int yax_cmpbunches(const int16_t *b1, const int16_t *b2)
static int yax_cmpbunches(const void *b1, const void *b2)
{
return (bunchdist[*b2] - bunchdist[*b1]);
return (bunchdist[*(int16_t *)b2] - bunchdist[*(int16_t *)b1]);
}
@ -1009,8 +1009,7 @@ void yax_drawrooms(void (*SpriteAnimFunc)(int32_t,int32_t,int32_t,int32_t),
yax_scanbunches(bbeg, numhere, (uint8_t *)gotsector);
qsort(&bunches[cf][bbeg], numhere, sizeof(int16_t),
(int(*)(const void *, const void *))&yax_cmpbunches);
qsort(&bunches[cf][bbeg], numhere, sizeof(int16_t), &yax_cmpbunches);
if (numhere > 1 && lev != YAX_MAXDRAWS-1)
Bmemset(lgotsector, 0, (numsectors+7)>>3);
@ -8459,7 +8458,7 @@ static inline int32_t raytrace(int32_t x3, int32_t y3, int32_t *x4, int32_t *y4)
#define _POSIX_REALTIME_SIGNALS
#endif
#include <signal.h>
static void sighandler(int32_t sig, const siginfo_t *info, void *ctx)
static void sighandler(int sig, siginfo_t *info, void *ctx)
{
const char *s;
UNREFERENCED_PARAMETER(ctx);
@ -8611,7 +8610,7 @@ int32_t initengine(void)
#if !defined _WIN32 && defined DEBUGGINGAIDS && !defined GEKKO
struct sigaction sigact, oldact;
memset(&sigact, 0, sizeof(sigact));
sigact.sa_sigaction = (void (*)(int, siginfo_t*, void*))sighandler;
sigact.sa_sigaction = &sighandler;
sigact.sa_flags = SA_SIGINFO;
sigaction(SIGFPE, &sigact, &oldact);
#endif
@ -15628,10 +15627,10 @@ static void sideview_getdist(int16_t sw, int16_t sect)
m32_sidedist[sw] = p->x*m32_viewplane.x + p->y*m32_viewplane.y + (p->z>>4)*m32_viewplane.z;
}
static int sideview_cmppoints(const int16_t *sw1, const int16_t *sw2)
static int sideview_cmppoints(const void *sw1, const void *sw2)
{
int32_t dist1 = m32_sidedist[*sw1];
int32_t dist2 = m32_sidedist[*sw2];
int32_t dist1 = m32_sidedist[*(int16_t *)sw1];
int32_t dist2 = m32_sidedist[*(int16_t *)sw2];
if (dist2>dist1)
return 1;
@ -16240,7 +16239,7 @@ void draw2dscreen(const vec3_t *pos, int16_t cursectnum, int16_t ange, int32_t z
if (m32_sideview)
{
qsort(m32_wallsprite, m32_swcnt, sizeof(int16_t), (int( *)(const void *, const void *))&sideview_cmppoints);
qsort(m32_wallsprite, m32_swcnt, sizeof(int16_t), &sideview_cmppoints);
for (i=0; i<m32_swcnt; i++) // shouldn't it go the other way around?
{

View file

@ -972,10 +972,13 @@ void(*installusertimercallback(void(*callback)(void)))(void)
//
// getvalidmodes() -- figure out what video modes are available
//
static int32_t sortmodes(const struct validmode_t *a, const struct validmode_t *b)
static int sortmodes(const void *a_, const void *b_)
{
int32_t x;
const struct validmode_t *a = (const struct validmode_t *)a_;
const struct validmode_t *b = (const struct validmode_t *)b_;
if ((x = a->fs - b->fs) != 0) return x;
if ((x = a->bpp - b->bpp) != 0) return x;
if ((x = a->xdim - b->xdim) != 0) return x;
@ -1093,7 +1096,7 @@ void getvalidmodes(void)
#undef CHECK
#undef ADDMODE
qsort((void *)validmode, validmodecnt, sizeof(struct validmode_t), (int32_t( *)(const void *,const void *))sortmodes);
qsort((void *)validmode, validmodecnt, sizeof(struct validmode_t), &sortmodes);
modeschecked=1;
}

View file

@ -1807,10 +1807,13 @@ static HRESULT WINAPI getvalidmodes_enum(DDSURFACEDESC *ddsd, VOID *udata)
return(DDENUMRET_OK);
}
static int32_t sortmodes(const struct validmode_t *a, const struct validmode_t *b)
static int sortmodes(const void *a_, const void *b_)
{
int32_t x;
const struct validmode_t *a = (const struct validmode_t *)a_;
const struct validmode_t *b = (const struct validmode_t *)b_;
if ((x = a->fs - b->fs) != 0) return x;
if ((x = a->bpp - b->bpp) != 0) return x;
if ((x = a->xdim - b->xdim) != 0) return x;
@ -1867,7 +1870,7 @@ void getvalidmodes(void)
ADDMODE(defaultres[i][0],defaultres[i][1],cdepths[j],0,-1)
}
qsort((void *)validmode, validmodecnt, sizeof(struct validmode_t), (int32_t( *)(const void *,const void *))sortmodes);
qsort((void *)validmode, validmodecnt, sizeof(struct validmode_t), &sortmodes);
modeschecked=1;
}

View file

@ -6169,21 +6169,21 @@ static void Keys3d(void)
else if (AIMING_AT_CEILING_OR_FLOOR)
{
sector[searchsector].lotag =
_getnumber256("Sector lotag: ", sector[searchsector].lotag, BTAG_MAX, 0, (void *(*)(int32_t))ExtGetSectorType);
_getnumber256("Sector lotag: ", sector[searchsector].lotag, BTAG_MAX, 0, &ExtGetSectorType);
}
else if (AIMING_AT_SPRITE)
{
if (sprite[searchwall].picnum == SECTOREFFECTOR)
{
sprite[searchwall].lotag =
_getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0+j, (void *(*)(int32_t))SectorEffectorTagText);
_getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0+j, &SectorEffectorTagText);
}
else if (sprite[searchwall].picnum == MUSICANDSFX)
{
int16_t oldtag = sprite[searchwall].lotag;
sprite[searchwall].lotag =
_getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0+j, (void *(*)(int32_t))MusicAndSFXTagText);
_getnumber256("Sprite lotag: ", sprite[searchwall].lotag, BTAG_MAX, 0+j, &MusicAndSFXTagText);
if ((sprite[searchwall].filler&1) && sprite[searchwall].lotag != oldtag)
{
@ -7795,7 +7795,7 @@ static void Keys2d(void)
j = 4*(j&1);
Bsprintf(buffer,"Sprite (%d) Lo-tag: ", i);
sprite[i].lotag = _getnumber16(buffer, sprite[i].lotag, BTAG_MAX, 0+j, sprite[i].picnum==SECTOREFFECTOR ?
(void *(*)(int32_t))SectorEffectorTagText : NULL);
&SectorEffectorTagText : NULL);
}
else if (linehighlight >= 0)
{
@ -7819,7 +7819,7 @@ static void Keys2d(void)
{
Bsprintf(buffer,"Sector (%d) Lo-tag: ", tcursectornum);
sector[tcursectornum].lotag =
_getnumber16(buffer, sector[tcursectornum].lotag, BTAG_MAX, 0, (void *(*)(int32_t))ExtGetSectorType);
_getnumber16(buffer, sector[tcursectornum].lotag, BTAG_MAX, 0, &ExtGetSectorType);
}
}
}

View file

@ -224,15 +224,15 @@ static inline void __fastcall VM_DoConditional(register int32_t condition)
}
}
static int32_t X_DoSortDefault(const int32_t *lv, const int32_t *rv)
static int X_DoSortDefault(const void *lv, const void *rv)
{
return (*rv - *lv);
return *(int32_t *)rv - *(int32_t *)lv;
}
static int32_t X_DoSort(const int32_t *lv, const int32_t *rv)
static int X_DoSort(const void *lv, const void *rv)
{
m32_sortvar1 = *lv;
m32_sortvar2 = *rv;
m32_sortvar1 = *(int32_t *)lv;
m32_sortvar2 = *(int32_t *)rv;
insptr = x_sortingstateptr;
VM_Execute(0);
return g_iReturnVar;
@ -1213,13 +1213,13 @@ skip_check:
if (state < 0)
{
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t(*)(const void *,const void *))X_DoSortDefault);
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), X_DoSortDefault);
}
else
{
x_sortingstateptr = script + statesinfo[state].ofs;
vm.g_st = 1+MAXEVENTS+state;
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), (int32_t(*)(const void *,const void *))X_DoSort);
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), X_DoSort);
vm.g_st = o_g_st;
insptr = end;
}

View file

@ -1076,9 +1076,9 @@ void Net_ReceiveMapUpdate(ENetEvent *event)
////////////////////////////////////////////////////////////////////////////////
// Map State
static int Net_CompareActors(const netactor_t *actor1, const netactor_t *actor2)
static int Net_CompareActors(const void *actor1, const void *actor2)
{
return actor1->netIndex - actor2->netIndex;
return ((netactor_t *)actor1)->netIndex - ((netactor_t *)actor2)->netIndex;
}
void Net_SaveMapState(netmapstate_t *save)
@ -1112,7 +1112,7 @@ void Net_SaveMapState(netmapstate_t *save)
}
}
qsort(save->actor, save->numActors, sizeof(netactor_t), (int( *)(const void *, const void *)) &Net_CompareActors);
qsort(save->actor, save->numActors, sizeof(netactor_t), &Net_CompareActors);
}
void Net_FillMapDiff(uint32_t fromRevision, uint32_t toRevision)