diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index 54d301a8f..781b13a17 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -165,31 +165,24 @@ void CheckUnusedFunctions::parseTokens(const Tokenizer &tokenizer, const char Fi const Token *funcname = nullptr; - if (tok->scope()->isExecutable() && Token::Match(tok->next(), "%var% (")) { + if (tok->scope()->isExecutable() && Token::Match(tok, "%var% (")) { + funcname = tok; + } else if (tok->scope()->isExecutable() && Token::Match(tok, "%var% <") && Token::simpleMatch(tok->linkAt(1), "> (")) { + funcname = tok; + } else if (Token::Match(tok, "[;{}.,()[=+-/|!?:]")) { funcname = tok->next(); - } - - else if (tok->scope()->isExecutable() && Token::Match(tok->next(), "%var% <") && Token::simpleMatch(tok->linkAt(2), "> (")) { - funcname = tok->next(); - } - - else if (Token::Match(tok, "[;{}.,()[=+-/|!?:] &| %var% [(),;]:}]")) { - funcname = tok->next(); - if (funcname->str() == "&") + if (funcname && funcname->str() == "&") funcname = funcname->next(); - } - - else if (Token::Match(tok, "[;{}.,()[=+-/|!?:] &| %var% :: %var%")) { - funcname = tok->next(); - if (funcname->str() == "&") + if (funcname && funcname->str() == "::") funcname = funcname->next(); - while (Token::Match(funcname,"%var% :: %var%")) + while (Token::Match(funcname, "%var% :: %var%")) funcname = funcname->tokAt(2); - if (!Token::Match(funcname, "%var% [(),;:}]")) + + if (!Token::Match(funcname, "%var% [(),;]:}]")) continue; } - else + if (!funcname) continue; // funcname ( => Assert that the end parentheses isn't followed by { diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 6f8555333..ca093ca0d 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -121,34 +121,51 @@ private: } void functionpointer() { + check("void foo() { }\n" + "int main() {\n" + " f(&foo);\n" + " return 0\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void foo() { }\n" + "int main() {\n" + " f(&::foo);\n" + " return 0\n" + "}"); + ASSERT_EQUALS("", errout.str()); + check("namespace abc {\n" - "void foo() { }\n" + " void foo() { }\n" "};\n" - "\n" - "int main()\n" - "{\n" + "int main() {\n" " f(&abc::foo);\n" " return 0\n" "}"); ASSERT_EQUALS("", errout.str()); check("namespace abc {\n" - "void foo() { }\n" + " void foo() { }\n" "};\n" - "\n" - "int main()\n" - "{\n" + "int main() {\n" " f = &abc::foo;\n" " return 0\n" "}"); ASSERT_EQUALS("", errout.str()); - check("namespace abc {\n" // #3875 - "void foo() { }\n" + check("namespace abc {\n" + " void foo() { }\n" "};\n" - "\n" - "int main()\n" - "{\n" + "int main() {\n" + " f = &::abc::foo;\n" + " return 0\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("namespace abc {\n" // #3875 + " void foo() { }\n" + "};\n" + "int main() {\n" " f(abc::foo);\n" " return 0\n" "}");