From 200b098471828b751d0a8a1cab7c302a9bb87941 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 14 Mar 2022 19:15:48 +0100 Subject: [PATCH] Fix #10516 FP for unused private function if address of function is taken (#3901) --- lib/checkclass.cpp | 2 +- lib/symboldatabase.cpp | 11 ++++++++--- test/testunusedprivfunc.cpp | 27 +++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index e4cd3842f..54dad5402 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1177,7 +1177,7 @@ static bool checkFunctionUsage(const Function *privfunc, const Scope* scope) for (const Variable &var : scope->varlist) { if (var.isStatic()) { - const Token* tok = Token::findmatch(scope->bodyEnd, "%varid% =|(|{", var.declarationId()); + const Token* tok = Token::findmatch(scope->bodyStart, "%varid% =|(|{", var.declarationId()); if (tok) tok = tok->tokAt(2); while (tok && tok->str() != ";") { diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 871d67cda..eff2d762b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1081,7 +1081,7 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass) // Set function call pointers for (const Token* tok = mTokenizer->list.front(); tok != mTokenizer->list.back(); tok = tok->next()) { - if (tok->isName() && !tok->function() && tok->varId() == 0 && Token::Match(tok, "%name% [(,)>]") && !isReservedName(tok->str())) { + if (tok->isName() && !tok->function() && tok->varId() == 0 && Token::Match(tok, "%name% [(,)>;]") && !isReservedName(tok->str())) { if (tok->next()->str() == ">" && !tok->next()->link()) continue; @@ -1089,7 +1089,7 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass) const Token *start = tok; while (Token::Match(start->tokAt(-2), "%name% ::")) start = start->tokAt(-2); - if (!Token::Match(start->previous(), "[(,<]") && !Token::Match(start->tokAt(-2), "[(,<] &")) + if (!Token::Match(start->previous(), "[(,<=]") && !Token::Match(start->tokAt(-2), "[(,<=] &") && !Token::Match(start, "%name% ;")) continue; } @@ -5352,8 +5352,13 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const else tok1 = nullptr; - if (tok1) + if (tok1) { + const Function* func = currScope->findFunction(tok1); + if (func) + return func; + currScope = currScope->findRecordInNestedList(tok1->str()); + } } if (tok1) diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index 34f022a1b..e868374ef 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -55,6 +55,7 @@ private: TEST_CASE(func_pointer4); // ticket #2807 TEST_CASE(func_pointer5); // ticket #2233 TEST_CASE(func_pointer6); // ticket #4787 + TEST_CASE(func_pointer7); // ticket #10516 TEST_CASE(ctor); TEST_CASE(ctor2); @@ -349,6 +350,32 @@ private: ASSERT_EQUALS("", errout.str()); } + void func_pointer7() { // #10516 + check("class C {\n" + " static void f() {}\n" + " static constexpr void(*p)() = f;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + check("class C {\n" + " static void f() {}\n" + " static constexpr void(*p)() = &f;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + check("class C {\n" + " static void f() {}\n" + " static constexpr void(*p)() = C::f;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + check("class C {\n" + " static void f() {}\n" + " static constexpr void(*p)() = &C::f;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + } + void ctor() { check("class PrivateCtor\n"