From c1f61327454fac9fbb313e640bc9092506abbcc7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 25 Nov 2023 22:57:07 +0100 Subject: [PATCH] Fix #12219 FP constParameterCallback for template argument (#5695) --- lib/symboldatabase.cpp | 17 ++++++----------- test/testsymboldatabase.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d7612bbea..ac053cfe5 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1101,23 +1101,18 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass) } // Set function call pointers + const Token* inTemplateArg = nullptr; for (Token* tok = mTokenizer.list.front(); tok != mTokenizer.list.back(); tok = tok->next()) { + if (inTemplateArg == nullptr && tok->link() && tok->str() == "<") + inTemplateArg = tok->link(); + if (inTemplateArg == tok) + inTemplateArg = nullptr; if (tok->isName() && !tok->function() && tok->varId() == 0 && ((tok->astParent() && tok->astParent()->isComparisonOp()) || Token::Match(tok, "%name% [{(,)>;]")) && !isReservedName(tok->str())) { if (tok->next()->str() == ">" && !tok->next()->link()) continue; - bool isTemplateArg = false; - if (!Token::Match(tok->next(), "(|{")) { - const Token *start = tok; - while (Token::Match(start->tokAt(-2), "%name% ::")) - start = start->tokAt(-2); - if (!Token::Match(start->previous(), "[(,<=]") && !Token::simpleMatch(start->previous(), "::") && !Token::Match(start->tokAt(-2), "[(,<=] &") && !Token::Match(start, "%name% ;")) - continue; - isTemplateArg = Token::simpleMatch(start->previous(), "<") || Token::simpleMatch(start->tokAt(-2), "<"); - } - const Function *function = findFunction(tok); - if (!function || (isTemplateArg && function->isConstructor())) + if (!function || (inTemplateArg && function->isConstructor())) continue; tok->function(function); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index ff6a6b6e6..d363f3245 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -454,6 +454,7 @@ private: TEST_CASE(findFunction51); // #11975 - method with same name in derived class TEST_CASE(findFunction52); TEST_CASE(findFunction53); + TEST_CASE(findFunction54); TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionGlobalScope); // ::foo @@ -7733,6 +7734,38 @@ private: ASSERT(S->function()->isConstructor()); } + void findFunction54() { + { + GET_SYMBOL_DB("struct S {\n" + " explicit S(int& r) { if (r) {} }\n" + " bool f(const std::map& m);\n" + "};\n"); + const Token* S = Token::findsimplematch(tokenizer.tokens(), "S ("); + ASSERT(S && S->function()); + ASSERT(S->function()->isConstructor()); + ASSERT(!S->function()->functionPointerUsage); + S = Token::findsimplematch(S->next(), "S >"); + ASSERT(S && S->type()); + ASSERT_EQUALS(S->type()->name(), "S"); + } + { + GET_SYMBOL_DB("struct S {\n" + " explicit S(int& r) { if (r) {} }\n" + " bool f(const std::map>& m);\n" + "};\n"); + const Token* S = Token::findsimplematch(tokenizer.tokens(), "S ("); + ASSERT(S && S->function()); + ASSERT(S->function()->isConstructor()); + ASSERT(!S->function()->functionPointerUsage); + S = Token::findsimplematch(S->next(), "S ,"); + ASSERT(S && S->type()); + ASSERT_EQUALS(S->type()->name(), "S"); + S = Token::findsimplematch(S->next(), "S >"); + ASSERT(S && S->type()); + ASSERT_EQUALS(S->type()->name(), "S"); + } + } + void findFunctionContainer() { { GET_SYMBOL_DB("void dostuff(std::vector v);\n"