diff --git a/lib/checkobsoletefunctions.cpp b/lib/checkobsoletefunctions.cpp index 4897e5ac0..14bf4b3a7 100644 --- a/lib/checkobsoletefunctions.cpp +++ b/lib/checkobsoletefunctions.cpp @@ -45,10 +45,13 @@ void CheckObsoleteFunctions::obsoleteFunctions() for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { - if (tok->isName() && tok->varId()==0 && tok->strAt(1) == "(" && !Token::Match(tok->previous(), ".|::|:|,")) + + if (tok->isName() && tok->varId()==0 && tok->strAt(1) == "(" && + (!Token::Match(tok->previous(), ".|::|:|,") || Token::simpleMatch(tok->previous()->previous(), "std :: gets"))) { // function declaration? - if (symbolDatabase->findFunctionByToken(tok)) + if ((tok->previous() && (tok->previous()->str() == "*" || tok->previous()->isName())) + || symbolDatabase->findFunctionByToken(tok)) { _obsoleteStandardFunctions.erase(tok->str()); _obsoletePosixFunctions.erase(tok->str()); @@ -61,7 +64,6 @@ void CheckObsoleteFunctions::obsoleteFunctions() // If checking an old code base it might be uninteresting to update obsolete functions. // Therefore this is "information" reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second); - break; } else { @@ -73,7 +75,6 @@ void CheckObsoleteFunctions::obsoleteFunctions() // If checking an old code base it might be uninteresting to update obsolete functions. // Therefore this is "information" reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second); - break; } } if (_settings->c99) @@ -82,7 +83,6 @@ void CheckObsoleteFunctions::obsoleteFunctions() if (it != _obsoleteC99Functions.end()) { reportError(tok->tokAt(1), Severity::style, "obsoleteFunctions"+it->first, it->second); - break; } } } diff --git a/test/testobsoletefunctions.cpp b/test/testobsoletefunctions.cpp index 562230b64..526306179 100644 --- a/test/testobsoletefunctions.cpp +++ b/test/testobsoletefunctions.cpp @@ -53,6 +53,16 @@ private: // declared function ticket #3121 TEST_CASE(test_declared_function); + + // test std::gets + TEST_CASE(test_std_gets); + + // multiple use of obsolete functions + TEST_CASE(test_multiple); + + // c declared function + TEST_CASE(test_c_declaration); + } void check(const char code[]) @@ -242,6 +252,46 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); } + + // test std::gets + void test_std_gets() + { + check("void f(char * str)\n" + "{\n" + " char *x = std::gets(str);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (style) Found obsolete function 'gets'. It is recommended to use the function 'fgets' instead\n", errout.str()); + } + + // multiple use + void test_multiple() + { + check("void f(char * str)\n" + "{\n" + " char *x = std::gets(str);\n" + " usleep( 1000 );\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (style) Found obsolete function 'gets'. It is recommended to use the function 'fgets' instead\n[test.cpp:4]: (style) Found obsolete function 'usleep'. It is recommended that new applications use the 'nanosleep' or 'setitimer' function\n", errout.str()); + } + + void test_c_declaration() + { + check("char * gets ( char * c ) ;\n" + "int main ()\n" + "{\n" + " char s [ 10 ] ;\n" + " gets ( s ) ;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("int getcontext(ucontext_t *ucp);\n" + "int f (ucontext_t *ucp)\n" + "{\n" + " getcontext ( ucp ) ;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + }; REGISTER_TEST(TestObsoleteFunctions)