diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 05f8fa8bd..bfc987d43 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1832,7 +1832,23 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const { - if (tok->function() && tok->function()->nestedIn == scope) + if (!tok->function()) { + for (std::list::const_iterator i = scope->functionList.cbegin(); i != scope->functionList.cend(); ++i) { + if (i->name() == tok->str()) { + const Token* tok2 = tok->tokAt(2); + size_t argsPassed = tok2->str() == ")" ? 0 : 1; + for (;;) { + tok2 = tok2->nextArgument(); + if (tok2) + argsPassed++; + else + break; + } + if (argsPassed == i->argCount() || (argsPassed < i->argCount() && argsPassed >= i->minArgCount())) + return true; + } + } + } else if (tok->function()->nestedIn == scope) return !tok->function()->isStatic(); // not found in this class @@ -1855,7 +1871,9 @@ bool CheckClass::isMemberFunc(const Scope *scope, const Token *tok) const bool CheckClass::isConstMemberFunc(const Scope *scope, const Token *tok) const { - if (tok->function() && tok->function()->nestedIn == scope) + if (!tok->function()) + return false; + else if (tok->function()->nestedIn == scope) return tok->function()->isConst(); // not found in this class diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index ca2cfd5cf..01130a5b0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -3846,6 +3846,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const // check each function against the arguments in the function call for a match for (std::size_t i = 0; i < matches.size();) { bool erased = false; + bool constFallback = false; const Function * func = matches[i]; size_t same = 0; @@ -3857,9 +3858,12 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const if (scope && scope->functionOf && scope->functionOf->isClassOrStruct()) { // check if isConst mismatches if (!(scope->function && scope->function->isConst() == func->isConst())) { - if (!erased) - ++i; - continue; + if (scope->function->isConst()) { + if (!erased) + ++i; + continue; + } + constFallback = true; } } } @@ -4072,10 +4076,14 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const size_t hasToBe = func->isVariadic() ? (func->argCount() - 1) : args; // check if all arguments matched - if (same == hasToBe) - return func; + if (same == hasToBe) { + if (constFallback) + fallback1Func = func; + else + return func; + } - if (!fallback1Func) { + else if (!fallback1Func) { if (same + fallback1 == hasToBe) fallback1Func = func; else if (!fallback2Func && same + fallback2 + fallback1 == hasToBe) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 82564c0c2..c5bfaa35b 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -287,6 +287,7 @@ private: TEST_CASE(findFunction15); TEST_CASE(findFunction16); TEST_CASE(findFunction17); + TEST_CASE(findFunction18); TEST_CASE(noexceptFunction1); TEST_CASE(noexceptFunction2); @@ -3785,6 +3786,22 @@ private: ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 2); } + void findFunction18() { + GET_SYMBOL_DB("class Fred {\n" + " void f(int i) { }\n" + " void f(float f) const { }\n" + " void a() { f(1); }\n" + " void b() { f(1.f); }\n" + "};"); + + ASSERT_EQUALS("", errout.str()); + + const Token *f = Token::findsimplematch(tokenizer.tokens(), "f ( 1 ) ;"); + ASSERT_EQUALS(true, db && f && f->function() && f->function()->tokenDef->linenr() == 2); + + f = Token::findsimplematch(tokenizer.tokens(), "f ( 1.f ) ;"); + ASSERT_EQUALS(true, f && f->function() && f->function()->tokenDef->linenr() == 3); + } #define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \ ASSERT_EQUALS(true, x != nullptr); \