diff --git a/cmake/compileroptions.cmake b/cmake/compileroptions.cmake index e9d1f7d4692..968c8bfe239 100644 --- a/cmake/compileroptions.cmake +++ b/cmake/compileroptions.cmake @@ -68,6 +68,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") add_compile_options(-Wsuggest-attribute=noreturn) add_compile_options(-Wno-shadow) # whenever a local variable or type declaration shadows another one add_compile_options_safe(-Wuseless-cast) + # add_compile_options_safe(-Wsuggest-attribute=returns_nonnull) # reports the warning even if the attribute is set elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 14 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 14) # TODO: verify this regression still exists in clang-15 diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index e511079d022..fb11991777f 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -362,7 +362,7 @@ namespace clangimport { void addFullScopeNameTokens(TokenList &tokenList, const Scope *recordScope); Scope *createScope(TokenList &tokenList, Scope::ScopeType scopeType, AstNodePtr astNode, const Token *def); Scope *createScope(TokenList &tokenList, Scope::ScopeType scopeType, const std::vector &children2, const Token *def); - Token *createTokensCall(TokenList &tokenList); + RET_NONNULL Token *createTokensCall(TokenList &tokenList); void createTokensFunctionDecl(TokenList &tokenList); void createTokensForCXXRecord(TokenList &tokenList); Token *createTokensVarDecl(TokenList &tokenList); diff --git a/lib/config.h b/lib/config.h index ebd2ebbbe14..1932364001f 100644 --- a/lib/config.h +++ b/lib/config.h @@ -121,11 +121,11 @@ # define DEPRECATED #endif -// TODO: GCC apparently also supports this but there is no documentation on it // returns_nonnull #if __has_cpp_attribute (gnu::returns_nonnull) # define RET_NONNULL [[gnu::returns_nonnull]] -#elif (defined(__clang__) && ((__clang_major__ > 3) || ((__clang_major__ == 3) && (__clang_minor__ >= 7)))) +#elif (defined(__clang__) && ((__clang_major__ > 3) || ((__clang_major__ == 3) && (__clang_minor__ >= 7)))) \ + || (defined(__GNUC__) && (__GNUC__ >= 9)) # define RET_NONNULL __attribute__((returns_nonnull)) #else # define RET_NONNULL diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 8668db48a3f..435f1b17ecb 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1103,8 +1103,8 @@ void CppCheck::checkNormalTokens(const Tokenizer &tokenizer) if (mSettings.useSingleJob() || !mSettings.buildDir.empty()) { // Analyse the tokens.. - - if (CTU::FileInfo * const fi1 = CTU::getFileInfo(tokenizer)) { + { + CTU::FileInfo * const fi1 = CTU::getFileInfo(tokenizer); if (!mSettings.buildDir.empty()) mAnalyzerInformation.setFileInfo("ctu", fi1->toString()); if (mSettings.useSingleJob()) diff --git a/lib/cppcheck.h b/lib/cppcheck.h index d59716d2662..fda7c6027c8 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -116,7 +116,7 @@ class CPPCHECKLIB CppCheck : ErrorLogger { * @brief Returns current version number as a string. * @return version, e.g. "1.38" */ - static const char * version(); + RET_NONNULL static const char * version(); /** * @brief Returns extra version info as a string. @@ -124,7 +124,7 @@ class CPPCHECKLIB CppCheck : ErrorLogger { * time/date etc. * @return extra version info, e.g. "04d42151" (Git commit id). */ - static const char * extraVersion(); + RET_NONNULL static const char * extraVersion(); /** * @brief Call all "getErrorMessages" in all registered Check classes. diff --git a/lib/ctu.h b/lib/ctu.h index dacc430bb0c..1efcae59397 100644 --- a/lib/ctu.h +++ b/lib/ctu.h @@ -144,7 +144,7 @@ namespace CTU { CPPCHECKLIB std::string getFunctionId(const Tokenizer &tokenizer, const Function *function); /** @brief Parse current TU and extract file info */ - CPPCHECKLIB FileInfo *getFileInfo(const Tokenizer &tokenizer); + CPPCHECKLIB RET_NONNULL FileInfo *getFileInfo(const Tokenizer &tokenizer); CPPCHECKLIB std::list getUnsafeUsage(const Tokenizer &tokenizer, const Settings &settings, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, MathLib::bigint *value)); diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index bba22b78b3f..5a8608e7e7c 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1015,7 +1015,7 @@ class CPPCHECKLIB Function { void isInlineKeyword(bool state) { setFlag(fIsInlineKeyword, state); } - const Token *setFlags(const Token *tok1, const Scope *scope); + RET_NONNULL const Token *setFlags(const Token *tok1, const Scope *scope); }; class CPPCHECKLIB Scope { @@ -1440,7 +1440,7 @@ class CPPCHECKLIB SymbolDatabase { void debugSymbolDatabase() const; void addClassFunction(Scope *&scope, const Token *&tok, const Token *argStart); - static Function *addGlobalFunctionDecl(Scope*& scope, const Token* tok, const Token *argStart, const Token* funcStart); + RET_NONNULL static Function *addGlobalFunctionDecl(Scope*& scope, const Token* tok, const Token *argStart, const Token* funcStart); Function *addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart); void addNewFunction(Scope *&scope, const Token *&tok); bool isFunction(const Token *tok, const Scope* outerScope, const Token *&funcStart, const Token *&argStart, const Token*& declEnd) const; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index c2067c94a73..4f76648ae92 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1346,7 +1346,7 @@ void TemplateSimplifier::simplifyTemplateAliases() const Token * const fromStart = args[argnr].first; const Token * const fromEnd = args[argnr].second->previous(); Token *temp = TokenList::copyTokens(tok1, fromStart, fromEnd, true); - const bool tempOK(temp && temp != tok1->next()); + const bool tempOK(temp != tok1->next()); tok1->deleteThis(); if (tempOK) tok1 = temp; // skip over inserted parameters diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index d3211f35d74..e16cd83a681 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2152,9 +2152,6 @@ void Tokenizer::simplifyTypedefCpp() tok2 = TokenList::copyTokens(tok2, argStart, argEnd); if (inTemplate) { - if (!tok2) - syntaxError(nullptr); - tok2 = tok2->next(); } diff --git a/lib/tokenize.h b/lib/tokenize.h index 46cf44f7cdc..1793ceb1c07 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -172,7 +172,7 @@ class CPPCHECKLIB Tokenizer { * '; int *p(0);' => '; int *p = 0;' */ void simplifyInitVar(); - static Token* initVar(Token* tok); + RET_NONNULL static Token* initVar(Token* tok); /** * Simplify the location of "static" and "const" qualifiers in diff --git a/lib/tokenlist.h b/lib/tokenlist.h index 09a74c4ca16..63e32b673b2 100644 --- a/lib/tokenlist.h +++ b/lib/tokenlist.h @@ -94,7 +94,7 @@ class CPPCHECKLIB TokenList { * @param one_line true=>copy all tokens to the same line as dest. false=>copy all tokens to dest while keeping the 'line breaks' * @return new location of last token copied */ - static Token *copyTokens(Token *dest, const Token *first, const Token *last, bool one_line = true); + RET_NONNULL static Token *copyTokens(Token *dest, const Token *first, const Token *last, bool one_line = true); /** * Create tokens from code. diff --git a/lib/vfvalue.h b/lib/vfvalue.h index 3eb1dd3b467..0a44a1c230b 100644 --- a/lib/vfvalue.h +++ b/lib/vfvalue.h @@ -327,10 +327,10 @@ namespace ValueFlow enum class LifetimeScope : std::uint8_t { Local, Argument, SubFunction, ThisPointer, ThisValue } lifetimeScope = LifetimeScope::Local; - static const char* toString(MoveKind moveKind); - static const char* toString(LifetimeKind lifetimeKind); - static const char* toString(LifetimeScope lifetimeScope); - static const char* toString(Bound bound); + RET_NONNULL static const char* toString(MoveKind moveKind); + RET_NONNULL static const char* toString(LifetimeKind lifetimeKind); + RET_NONNULL static const char* toString(LifetimeScope lifetimeScope); + RET_NONNULL static const char* toString(Bound bound); /** How known is this value */ enum class ValueKind : std::uint8_t { diff --git a/lib/xml.h b/lib/xml.h index 86377f77dac..faf121dcdf4 100644 --- a/lib/xml.h +++ b/lib/xml.h @@ -22,6 +22,7 @@ #include "config.h" #include "path.h" +SUPPRESS_WARNING_GCC_PUSH("-Wsuggest-attribute=returns_nonnull") SUPPRESS_WARNING_CLANG_PUSH("-Wzero-as-null-pointer-constant") SUPPRESS_WARNING_CLANG_PUSH("-Wsuggest-destructor-override") SUPPRESS_WARNING_CLANG_PUSH("-Winconsistent-missing-destructor-override") @@ -33,6 +34,7 @@ SUPPRESS_WARNING_CLANG_POP SUPPRESS_WARNING_CLANG_POP SUPPRESS_WARNING_CLANG_POP SUPPRESS_WARNING_CLANG_POP +SUPPRESS_WARNING_GCC_POP inline static tinyxml2::XMLError xml_LoadFile(tinyxml2::XMLDocument& doc, const char* filename) {