Permalink
Browse files

Fix some compiler warnings (#917)

* Consistently declare Com_Error implementations as noreturn

According to comments in code/game/g_public.h (whose version was
already tagged noreturn), for function pointers this only works with
the gcc/clang-specific spelling __attribute__((noreturn)), and not with
the gcc/clang/MSVC abstraction NORETURN. For function implementations,
we can use NORETURN to get MSVC support too.

This lets the compiler reason about what returns and what doesn't,
and in particular silences gcc warnings about functions that
are declared NORETURN but that did appear to return. They didn't,
because they ended with a call to (a function pointer that
eventually calls) Com_Error, but without these annotations
the compiler couldn't know that.

Signed-off-by: Simon McVittie <smcv@debian.org>

* AI_ClosestGroupEntityNumToPoint: Remove, unused

It issues compiler warnings (or did until recently), and git grep says
nothing actually calls or mentions this function.

Signed-off-by: Simon McVittie <smcv@debian.org>

* Icarus: Squash a compiler warning about possibly uninitialized length

clang can see that BufferRead() does not always assign to length,
issuing this warning:

IcarusImplementation.cpp|601 col 13| warning: ‘length’ may be used uninitialized in this function [-Wmaybe-uninitialized]

(This only happens if the buffer is null, in which case we have
bigger problems.)

Signed-off-by: Simon McVittie <smcv@debian.org>

* Move definition of NORETURN to q_platform.h

Signed-off-by: Simon McVittie <smcv@debian.org>

* Introduce NORETURN_PTR, a version of NORETURN for function pointers

This expands to the same thing as NORETURN on gcc (and clang), but
expands to nothing on MSVC.

Signed-off-by: Simon McVittie <smcv@debian.org>

* Define NORETURN, NORETURN_PTR for non-gcc non-MSVC compilers

Signed-off-by: Simon McVittie <smcv@debian.org>
  • Loading branch information...
smcv authored and xycaleth committed Jul 7, 2017
1 parent be7dbae commit 18324bace6d39b884115fdd77e9005af0b59617c
View
@@ -665,7 +665,7 @@ const char *CG_ConfigString( int index );
const char *CG_Argv( int arg );
void QDECL CG_Printf( const char *msg, ... );
void QDECL CG_Error( const char *msg, ... );
NORETURN void QDECL CG_Error( const char *msg, ... );
void CG_StartMusic( qboolean bForceStart );
@@ -921,7 +921,7 @@ qboolean CG_Credits_Draw( void );
void cgi_Printf( const char *fmt );
// abort the game
void cgi_Error( const char *fmt );
NORETURN void cgi_Error( const char *fmt );
// milliseconds should only be used for performance tuning, never
// for anything game related. Get time from the CG_DrawActiveFrame parameter
View
@@ -570,7 +570,7 @@ void CG_Printf( const char *msg, ... ) {
cgi_Printf( text );
}
void CG_Error( const char *msg, ... ) {
NORETURN void CG_Error( const char *msg, ... ) {
va_list argptr;
char text[1024];
@@ -46,7 +46,7 @@ void cgi_Printf( const char *fmt ) {
Q_syscall( CG_PRINT, fmt );
}
void cgi_Error( const char *fmt ) {
NORETURN void cgi_Error( const char *fmt ) {
Q_syscall( CG_ERROR, fmt );
// shut up GCC warning about returning functions, because we know better
exit(1);
View
@@ -157,9 +157,7 @@ typedef struct {
void (*FlushCamFile)();
// abort the game
// (this is not NORETURN because MSVC's version of NORETURN is not
// supported for function pointers)
__attribute__((noreturn)) void (*Error)( int, const char *fmt, ... );
NORETURN_PTR void (*Error)( int, const char *fmt, ... );
// get current time for profiling reasons
// this should NOT be used for any game related tasks,
@@ -592,7 +592,7 @@ int CIcarus::LoadSignals()
for ( int i = 0; i < numSignals; i++ )
{
char buffer[1024];
int length;
int length = 0;
//Get the size of the string
BufferRead( &length, sizeof( length ) );
View
@@ -141,12 +141,6 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#define Q_EXPORT
#endif
#if defined(__GNUC__)
#define NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define NORETURN __declspec(noreturn)
#endif
// this is the define for determining if we have an asm version of a C function
#if (defined(_M_IX86) || defined(__i386__)) && !defined(__sun__)
#define id386 1
@@ -34,7 +34,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
typedef struct {
void (QDECL *Printf) ( int printLevel, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
void (QDECL *Error) ( int errorLevel, const char *fmt, ...) __attribute__ ((noreturn, format (printf, 2, 3)));
void (QDECL *Error) ( int errorLevel, const char *fmt, ...) NORETURN_PTR __attribute__ ((format (printf, 2, 3)));
// milliseconds should only be used for profiling, never for anything game related. Get time from the refdef
int (*Milliseconds) ( void );
View
@@ -38,7 +38,7 @@ typedef struct {
void (*Printf)( const char *fmt, ... );
// abort the game
void (*Error)( int level, const char *fmt, ... );
NORETURN_PTR void (*Error)( int level, const char *fmt, ... );
// console variable interaction
void (*Cvar_Set)( const char *name, const char *value );
View
@@ -649,7 +649,7 @@ const char *CG_ConfigString( int index );
const char *CG_Argv( int arg );
void QDECL CG_Printf( const char *msg, ... );
void QDECL CG_Error( const char *msg, ... );
NORETURN void QDECL CG_Error( const char *msg, ... );
void CG_StartMusic( qboolean bForceStart );
@@ -911,7 +911,7 @@ qboolean CG_Credits_Draw( void );
void cgi_Printf( const char *fmt );
// abort the game
void cgi_Error( const char *fmt );
NORETURN void cgi_Error( const char *fmt );
// milliseconds should only be used for performance tuning, never
// for anything game related. Get time from the CG_DrawActiveFrame parameter
@@ -536,7 +536,7 @@ void CG_Printf( const char *msg, ... ) {
cgi_Printf( text );
}
void CG_Error( const char *msg, ... ) {
NORETURN void CG_Error( const char *msg, ... ) {
va_list argptr;
char text[1024];
@@ -45,7 +45,7 @@ void cgi_Printf( const char *fmt ) {
Q_syscall( CG_PRINT, fmt );
}
void cgi_Error( const char *fmt ) {
NORETURN void cgi_Error( const char *fmt ) {
Q_syscall( CG_ERROR, fmt );
// shut up GCC warning about returning functions, because we know better
exit(1);
View
@@ -95,38 +95,6 @@ int AI_GetGroupSize( gentity_t *ent, int radius )
return AI_GetGroupSize( ent->currentOrigin, radius, ent->client->playerTeam, ent );
}
extern int NAV_FindClosestWaypointForPoint( gentity_t *ent, vec3_t point );
int AI_ClosestGroupEntityNumToPoint( AIGroupInfo_t &group, vec3_t point )
{
int markerWP = WAYPOINT_NONE;
int cost, bestCost = Q3_INFINITE;
int closest = ENTITYNUM_NONE;
if ( group.numGroup <= 0 )
{
return ENTITYNUM_NONE;
}
markerWP = NAV_FindClosestWaypointForPoint( &g_entities[group.member[0].number], point );
if ( markerWP == WAYPOINT_NONE )
{
return ENTITYNUM_NONE;
}
for ( int i = 0; i < group.numGroup; i++ )
{
cost = navigator.GetPathCost( group.member[i].waypoint, markerWP );
if ( cost < bestCost )
{
bestCost = cost;
closest = group.member[i].number;
}
}
return closest;
}
void AI_SetClosestBuddy( AIGroupInfo_t *group )
{
int i, j;
View
@@ -147,7 +147,7 @@ typedef struct {
void (*FlushCamFile)();
// abort the game
void (*Error)( int, const char *fmt, ... );
NORETURN_PTR void (*Error)( int level, const char *fmt, ... );
// get current time for profiling reasons
// this should NOT be used for any game related tasks,
View
@@ -476,7 +476,7 @@ typedef enum cgameExportLegacy_e {
typedef struct cgameImport_s {
// common
void (*Print) ( const char *msg, ... );
void (*Error) ( int level, const char *error, ... );
NORETURN_PTR void (*Error)( int level, const char *fmt, ... );
void (*SnapVector) ( float *v );
int (*MemoryRemaining) ( void );
void (*RegisterSharedMemory) ( char *memory );
@@ -44,7 +44,7 @@ int PASSFLOAT( float x ) {
void trap_Print( const char *fmt ) {
Q_syscall( CG_PRINT, fmt );
}
void trap_Error( const char *fmt ) {
NORETURN void trap_Error( const char *fmt ) {
Q_syscall( CG_ERROR, fmt );
exit(1);
}
@@ -706,7 +706,7 @@ float CGSyscall_R_GetDistanceCull( void ) { float tmp; trap_R_GetDistanceCull( &
void CGSyscall_FX_PlayEffectID( int id, vec3_t org, vec3_t fwd, int vol, int rad, qboolean isPortal ) { if ( isPortal ) trap_FX_PlayPortalEffectID( id, org, fwd, vol, rad ); else trap_FX_PlayEffectID( id, org, fwd, vol, rad ); }
void CGSyscall_G2API_CollisionDetect( CollisionRecord_t *collRecMap, void* ghoul2, const vec3_t angles, const vec3_t position, int frameNumber, int entNum, vec3_t rayStart, vec3_t rayEnd, vec3_t scale, int traceFlags, int useLod, float fRadius ) { trap_G2API_CollisionDetect( collRecMap, ghoul2, angles, position, frameNumber, entNum, rayStart, rayEnd, scale, traceFlags, useLod, fRadius ); }
void QDECL CG_Error( int level, const char *error, ... ) {
NORETURN void QDECL CG_Error( int level, const char *error, ... ) {
va_list argptr;
char text[1024] = {0};
View
@@ -97,39 +97,6 @@ int AI_GetGroupSize2( gentity_t *ent, int radius )
return AI_GetGroupSize( ent->r.currentOrigin, radius, (team_t)ent->client->playerTeam, ent );
}
extern int NAV_FindClosestWaypointForPoint( gentity_t *ent, vec3_t point );
int AI_ClosestGroupEntityNumToPoint( AIGroupInfo_t *group, vec3_t point )
{
int markerWP = WAYPOINT_NONE;
int cost, bestCost = Q3_INFINITE;
int closest = ENTITYNUM_NONE;
int i;
if ( group == NULL || group->numGroup <= 0 )
{
return ENTITYNUM_NONE;
}
markerWP = NAV_FindClosestWaypointForPoint( &g_entities[group->member[0].number], point );
if ( markerWP == WAYPOINT_NONE )
{
return ENTITYNUM_NONE;
}
for ( i = 0; i < group->numGroup; i++ )
{
cost = trap->Nav_GetPathCost( group->member[i].waypoint, markerWP );
if ( cost < bestCost )
{
bestCost = cost;
closest = group->member[i].number;
}
}
return closest;
}
void AI_SetClosestBuddy( AIGroupInfo_t *group )
{
int i, j;
View
@@ -760,7 +760,7 @@ typedef enum gameExportLegacy_e {
typedef struct gameImport_s {
// misc
void (*Print) ( const char *msg, ... );
void (*Error) ( int level, const char *error, ... );
NORETURN_PTR void (*Error)( int level, const char *fmt, ... );
int (*Milliseconds) ( void );
void (*PrecisionTimerStart) ( void **timer );
int (*PrecisionTimerEnd) ( void *timer );
View
@@ -43,7 +43,7 @@ int PASSFLOAT( float x ) {
void trap_Print( const char *fmt ) {
Q_syscall( G_PRINT, fmt );
}
void trap_Error( const char *fmt ) {
NORETURN void trap_Error( const char *fmt ) {
Q_syscall( G_ERROR, fmt );
exit(1);
}
@@ -1010,7 +1010,7 @@ void SVSyscall_Trace( trace_t *results, const vec3_t start, const vec3_t mins, c
trap_Trace( results, start, mins, maxs, end, passEntityNum, contentmask );
}
void QDECL G_Error( int errorLevel, const char *error, ... ) {
NORETURN void QDECL G_Error( int errorLevel, const char *error, ... ) {
va_list argptr;
char text[1024];
@@ -130,12 +130,6 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#define Q_EXPORT
#endif
#if defined(__GNUC__)
#define NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define NORETURN __declspec(noreturn)
#endif
// this is the define for determining if we have an asm version of a C function
#if (defined(_M_IX86) || defined(__i386__)) && !defined(__sun__)
#define id386 1
@@ -693,7 +687,7 @@ qboolean Info_NextPair( const char **s, char *key, char *value );
// this is only here so the functions in q_shared.c and bg_*.c can link
#if defined( _GAME ) || defined( _CGAME ) || defined( UI_BUILD )
void (*Com_Error)( int level, const char *error, ... );
NORETURN_PTR void (*Com_Error)( int level, const char *error, ... );
void (*Com_Printf)( const char *msg, ... );
#else
void NORETURN QDECL Com_Error( int level, const char *error, ... );
@@ -252,7 +252,7 @@ typedef struct refexport_s {
//
typedef struct refimport_s {
void (QDECL *Printf) ( int printLevel, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
void (QDECL *Error) ( int errorLevel, const char *fmt, ...) __attribute__ ((noreturn, format (printf, 2, 3)));
void (QDECL *Error) ( int errorLevel, const char *fmt, ...) NORETURN_PTR __attribute__ ((format (printf, 2, 3)));
void (QDECL *OPrintf) ( const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
// milliseconds should only be used for profiling, never for anything game related. Get time from the refdef
View
@@ -228,7 +228,7 @@ typedef enum uiExportLegacy_e {
typedef struct uiImport_s {
void (*Print) ( const char *msg, ... );
void (*Error) ( int level, const char *error, ... );
NORETURN_PTR void (*Error)( int level, const char *fmt, ... );
int (*Milliseconds) ( void );
int (*RealTime) ( qtime_t *qtime );
int (*MemoryRemaining) ( void );
View
@@ -461,7 +461,7 @@ typedef struct displayContextDef_s {
void (*getBindingBuf) ( int keynum, char *buf, int buflen );
void (*setBinding) ( int keynum, const char *binding );
void (*executeText) ( int exec_when, const char *text );
void (*Error) ( int level, const char *error, ... );
NORETURN_PTR void (*Error)( int level, const char *fmt, ... );
void (*Print) ( const char *msg, ... );
void (*Pause) ( qboolean b );
int (*ownerDrawWidth) ( int ownerDraw, float scale );
View
@@ -43,7 +43,7 @@ int PASSFLOAT( float x ) {
void trap_Print( const char *string ) {
Q_syscall( UI_PRINT, string );
}
void trap_Error( const char *string ) {
NORETURN void trap_Error( const char *string ) {
Q_syscall( UI_ERROR, string );
exit(1);
}
@@ -469,7 +469,7 @@ void UISyscall_RemoveCommand( const char *cmd_name )
Com_Printf( S_COLOR_YELLOW "WARNING: trap->ext.RemoveCommand() is only supported with OpenJK mod API!\n" );
}
void QDECL UI_Error( int level, const char *error, ... ) {
NORETURN void QDECL UI_Error( int level, const char *error, ... ) {
va_list argptr;
char text[4096] = {0};
@@ -193,6 +193,18 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#define IS_NOEXCEPT(x) noexcept(x)
#endif
#if defined(__GNUC__)
#define NORETURN __attribute__((noreturn))
#define NORETURN_PTR __attribute__((noreturn))
#elif defined(_MSC_VER)
#define NORETURN __declspec(noreturn)
// __declspec doesn't work on function pointers
#define NORETURN_PTR /* nothing */
#else
#define NORETURN /* nothing */
#define NORETURN_PTR /* nothing */
#endif
#define OVERRIDE override
#if defined(__cplusplus)

0 comments on commit 18324ba

Please sign in to comment.