diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index d007b858e15..97493857429 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5586,7 +5586,7 @@ bool Scope::hasInlineOrLambdaFunction(const Token** tokStart, bool onlyInline) c }); } -void Scope::findFunctionInBase(const std::string & name, nonneg int args, std::vector & matches) const +void Scope::findFunctionInBase(const Token* tok, nonneg int args, std::vector & matches) const { if (isClassOrStruct() && definedType && !definedType->derivedFrom.empty()) { const std::vector &derivedFrom = definedType->derivedFrom; @@ -5596,16 +5596,18 @@ void Scope::findFunctionInBase(const std::string & name, nonneg int args, std::v if (base->classScope == this) // Ticket #5120, #5125: Recursive class; tok should have been found already continue; - auto range = utils::as_const(base->classScope->functionMap).equal_range(name); + auto range = utils::as_const(base->classScope->functionMap).equal_range(tok->str()); for (auto it = range.first; it != range.second; ++it) { const Function *func = it->second; + if (func->isDestructor() && !Token::simpleMatch(tok->tokAt(-1), "~")) + continue; if ((func->isVariadic() && args >= (func->argCount() - 1)) || (args == func->argCount() || (args < func->argCount() && args >= func->minArgCount()))) { matches.push_back(func); } } - base->classScope->findFunctionInBase(name, args, matches); + base->classScope->findFunctionInBase(tok, args, matches); } } } @@ -5791,7 +5793,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst, Referen const std::size_t numberOfMatchesNonBase = matches.size(); // check in base classes - findFunctionInBase(tok->str(), args, matches); + findFunctionInBase(tok, args, matches); // Non-call => Do not match parameters if (!isCall) { diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 6d16fddbe84..1ab399762fa 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1205,7 +1205,7 @@ class CPPCHECKLIB Scope { */ bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const; - void findFunctionInBase(const std::string & name, nonneg int args, std::vector & matches) const; + void findFunctionInBase(const Token* tok, nonneg int args, std::vector & matches) const; /** @brief initialize varlist */ void getVariableList(const Token *start, const Token *end); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 147f53b257f..8759db8a31e 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -532,6 +532,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(findFunction58); // #13310 TEST_CASE(findFunction59); TEST_CASE(findFunction60); + TEST_CASE(findFunction61); TEST_CASE(findFunctionRef1); TEST_CASE(findFunctionRef2); // #13328 TEST_CASE(findFunctionContainer); @@ -8650,6 +8651,19 @@ class TestSymbolDatabase : public TestFixture { ASSERT(fun && !fun->function()); } + void findFunction61() { + GET_SYMBOL_DB("namespace N {\n" // #13975 + " struct B {\n" + " virtual ~B() = default;\n" + " };\n" + " struct D : B {\n" + " D() : B() {}\n" + " };\n" + "}\n"); + const Token* fun = Token::findsimplematch(tokenizer.tokens(), "B ( ) {"); + ASSERT(fun && !fun->function()); + } + void findFunctionRef1() { GET_SYMBOL_DB("struct X {\n" " const std::vector getInts() const & { return mInts; }\n"