Properly handle format analysis

Rename ATTRIBUTE_PRINTF to
- ID_STATIC_ATTRIBUTE_PRINTF
- ID_INSTANCE_ATTRIBUTE_PRINTF
since for instance functions, this has to be taken into account, too.
Add format analysis to idLib, DeclManager and idTokenParser functions.
Add support for clang.
This commit is contained in:
Andreas Bergmeier 2014-02-22 17:02:06 +01:00
parent 7b6ceb48c8
commit 4d9970b148
5 changed files with 16 additions and 13 deletions

View file

@ -209,7 +209,7 @@ public:
//BSM Added for the material editors rename capabilities
virtual bool RenameDecl( declType_t type, const char* oldName, const char* newName );
virtual void MediaPrint( VERIFY_FORMAT_STRING const char* fmt, ... );
virtual void MediaPrint( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF(1, 2);
virtual void WritePrecacheCommands( idFile* f );
virtual const idMaterial* FindMaterial( const char* name, bool makeDefault = true );

View file

@ -156,8 +156,8 @@ public:
int ExpectAnyToken( idToken* token );
void SetMarker() {}
void UnreadToken( const idToken* token );
void Error( VERIFY_FORMAT_STRING const char* str, ... );
void Warning( VERIFY_FORMAT_STRING const char* str, ... );
void Error( VERIFY_FORMAT_STRING const char* str, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF(1, 2);
void Warning( VERIFY_FORMAT_STRING const char* str, ... ) ID_INSTANCE_ATTRIBUTE_PRINTF(1, 2);
int ParseInt();
bool ParseBool();
float ParseFloat( bool* errorFlag = NULL );

View file

@ -62,12 +62,12 @@ public:
static void ShutDown();
// wrapper to idCommon functions
static void Printf( const char* fmt, ... );
static void PrintfIf( const bool test, const char* fmt, ... );
NO_RETURN static void Error( const char* fmt, ... );
NO_RETURN static void FatalError( const char* fmt, ... );
static void Warning( const char* fmt, ... );
static void WarningIf( const bool test, const char* fmt, ... );
static void Printf ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
static void PrintfIf ( const bool test, VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 2, 3 );
NO_RETURN static void Error ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
NO_RETURN static void FatalError( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
static void Warning ( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
static void WarningIf ( const bool test, VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 2, 3 );
// the extra check for mainThreadInitialized is necessary for this to be accurate
// when called by startup code that happens before idLib::Init

View file

@ -402,7 +402,7 @@ public:
static const int INVALID_POSITION = -1;
};
char* va( VERIFY_FORMAT_STRING const char* fmt, ... ) ATTRIBUTE_PRINTF( 1, 2 );
char* va( VERIFY_FORMAT_STRING const char* fmt, ... ) ID_STATIC_ATTRIBUTE_PRINTF( 1, 2 );
/*
================================================================================================

View file

@ -213,16 +213,19 @@ bulk of the codebase, so it is the best place for analyze pragmas.
#include <CodeAnalysis\SourceAnnotations.h>
#define VERIFY_FORMAT_STRING [SA_FormatString(Style="printf")]
// DG: alternative for GCC with attribute (NOOP for MSVC)
#define ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX)
#define ID_STATIC_ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX)
#elif defined(__GNUC__) // FIXME: what about clang?
#else
#define VERIFY_FORMAT_STRING
// STRIDX: index of format string in function arguments (first arg == 1)
// FIRSTARGIDX: index of first argument for the format string
#define ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX) __attribute__ ((format (printf, STRIDX, FIRSTARGIDX)))
#define ID_STATIC_ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX) __attribute__ ((format (printf, STRIDX, FIRSTARGIDX)))
// DG end
#endif // _MSC_VER
// This needs to be handled so shift by 1
#define ID_INSTANCE_ATTRIBUTE_PRINTF(STRIDX, FIRSTARGIDX) ID_STATIC_ATTRIBUTE_PRINTF((STRIDX+1),(FIRSTARGIDX+1))
// We need to inform the compiler that Error() and FatalError() will
// never return, so any conditions that leeds to them being called are
// guaranteed to be false in the following code