Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const Function *> & matches) const
void Scope::findFunctionInBase(const Token* tok, nonneg int args, std::vector<const Function *> & matches) const
{
if (isClassOrStruct() && definedType && !definedType->derivedFrom.empty()) {
const std::vector<Type::BaseInfo> &derivedFrom = definedType->derivedFrom;
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion lib/symboldatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<const Function *> & matches) const;
void findFunctionInBase(const Token* tok, nonneg int args, std::vector<const Function *> & matches) const;

/** @brief initialize varlist */
void getVariableList(const Token *start, const Token *end);
Expand Down
14 changes: 14 additions & 0 deletions test/testsymboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<int> getInts() const & { return mInts; }\n"
Expand Down
Loading