From 4d9970b14854de2b1e0505f57fdeb8ddd535235b Mon Sep 17 00:00:00 2001 From: Andreas Bergmeier Date: Sat, 22 Feb 2014 17:02:06 +0100 Subject: [PATCH] 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. --- neo/framework/DeclManager.cpp | 2 +- neo/framework/TokenParser.h | 4 ++-- neo/idlib/Lib.h | 12 ++++++------ neo/idlib/Str.h | 2 +- neo/idlib/sys/sys_defines.h | 9 ++++++--- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/neo/framework/DeclManager.cpp b/neo/framework/DeclManager.cpp index 0750eb2d..1b6bb4fb 100644 --- a/neo/framework/DeclManager.cpp +++ b/neo/framework/DeclManager.cpp @@ -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 ); diff --git a/neo/framework/TokenParser.h b/neo/framework/TokenParser.h index 0b3f482a..5fe1ed5b 100644 --- a/neo/framework/TokenParser.h +++ b/neo/framework/TokenParser.h @@ -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 ); diff --git a/neo/idlib/Lib.h b/neo/idlib/Lib.h index d070e873..9e7fbf2e 100644 --- a/neo/idlib/Lib.h +++ b/neo/idlib/Lib.h @@ -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 diff --git a/neo/idlib/Str.h b/neo/idlib/Str.h index b5c9281b..331ad139 100644 --- a/neo/idlib/Str.h +++ b/neo/idlib/Str.h @@ -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 ); /* ================================================================================================ diff --git a/neo/idlib/sys/sys_defines.h b/neo/idlib/sys/sys_defines.h index 8dc8143d..11d3fee8 100644 --- a/neo/idlib/sys/sys_defines.h +++ b/neo/idlib/sys/sys_defines.h @@ -213,16 +213,19 @@ bulk of the codebase, so it is the best place for analyze pragmas. #include #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