diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 9281b54a3..8935e5073 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1997,7 +1997,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const Token::simpleMatch(tok->linkAt(1), ") {") && (!tok->previous() || Token::Match(tok->previous(), ";|}"))) { if (mTokenizer.isC()) { - debugMessage(tok, "debug", "SymbolDatabase::isFunction found C function '" + tok->str() + "' without a return type."); + returnImplicitIntError(tok); *funcStart = tok; *argStart = tok->next(); *declEnd = tok->linkAt(1)->next(); @@ -3522,6 +3522,19 @@ void SymbolDatabase::debugMessage(const Token *tok, const std::string &type, con } } +void SymbolDatabase::returnImplicitIntError(const Token *tok) const +{ + if (tok && mSettings.severity.isEnabled(Severity::portability) && mSettings.standards.c != Standards::C89 && mErrorLogger) { + const std::list locationList(1, tok); + const ErrorMessage errmsg(locationList, &mTokenizer.list, + Severity::portability, + "returnImplicitInt", + "Omitted return type of function '" + tok->str() + "' defaults to int, this is not supported by ISO C99 and later standards.", + Certainty::normal); + mErrorLogger->reportErr(errmsg); + } +} + const Function* Type::getFunction(const std::string& funcName) const { if (classScope) { diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index a235527df..f9f4039ff 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1371,6 +1371,8 @@ public: */ void debugMessage(const Token *tok, const std::string &type, const std::string &msg) const; + void returnImplicitIntError(const Token *tok) const; + void printOut(const char * title = nullptr) const; void printVariable(const Variable *var, const char *indent) const; void printXml(std::ostream &out) const; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 06d4d1915..cf92cb27c 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -2380,12 +2380,12 @@ private: } #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) - void check_(const char* file, int line, const char code[], bool debug = true, const char filename[] = "test.cpp") { + void check_(const char* file, int line, const char code[], bool debug = true, const char filename[] = "test.cpp", const Settings* pSettings = nullptr) { // Clear the error log errout.str(""); // Check.. - const Settings settings = settingsBuilder(settings1).debugwarnings(debug).build(); + const Settings settings = settingsBuilder(pSettings ? *pSettings : settings1).debugwarnings(debug).build(); // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -2986,7 +2986,12 @@ private: ASSERT_EQUALS("", errout.str()); check("main(int argc, char *argv[]) { }", true, "test.c"); - ASSERT_EQUALS("[test.c:1]: (debug) SymbolDatabase::isFunction found C function 'main' without a return type.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); + + const Settings s = settingsBuilder(settings1).severity(Severity::portability).build(); + check("main(int argc, char *argv[]) { }", false, "test.c", &s); + ASSERT_EQUALS("[test.c:1]: (portability) Omitted return type of function 'main' defaults to int, this is not supported by ISO C99 and later standards.\n", + errout.str()); check("namespace boost {\n" " std::locale generate_locale()\n"