diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 9961d783b4a..18d10578ea1 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5698,7 +5698,7 @@ static bool hasMatchingConstructor(const Scope* classScope, const ValueType* arg }); } -const Function* Scope::findFunction(const Token *tok, bool requireConst) const +const Function* Scope::findFunction(const Token *tok, bool requireConst, Reference ref) const { const bool isCall = Token::Match(tok->next(), "(|{"); @@ -5713,6 +5713,8 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const auto range = scope->functionMap.equal_range(tok->str()); for (std::multimap::const_iterator it = range.first; it != range.second; ++it) { const Function *func = it->second; + if (ref == Reference::LValue && func->hasRvalRefQualifier()) + continue; if (!isCall || args == func->argCount() || (func->isVariadic() && args >= (func->minArgCount() - 1)) || (args < func->argCount() && args >= func->minArgCount())) { @@ -6066,7 +6068,7 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const else if (Token::Match(tok->tokAt(-2), "!!this .")) { const Token* tok1 = tok->previous()->astOperand1(); if (tok1 && tok1->valueType() && tok1->valueType()->typeScope) - return tok1->valueType()->typeScope->findFunction(tok, tok1->valueType()->constness == 1); + return tok1->valueType()->typeScope->findFunction(tok, tok1->valueType()->constness == 1, tok1->valueType()->reference); if (tok1 && Token::Match(tok1->previous(), "%name% (") && tok1->previous()->function() && tok1->previous()->function()->retDef) { ValueType vt = ValueType::parseDecl(tok1->previous()->function()->retDef, mSettings); diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 5b4ee0338c6..a594c84b2ac 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -49,6 +49,12 @@ class SymbolDatabase; class Tokenizer; class ValueType; +enum class Reference : std::uint8_t { + None, + LValue, + RValue +}; + /** * @brief Access control enumerations. */ @@ -1128,7 +1134,7 @@ class CPPCHECKLIB Scope { * @param requireConst if const refers to a const variable only const methods should be matched * @return pointer to function if found or NULL if not found */ - const Function *findFunction(const Token *tok, bool requireConst=false) const; + const Function *findFunction(const Token *tok, bool requireConst=false, Reference ref=Reference::None) const; const Scope *findRecordInNestedList(const std::string & name, bool isC = false) const; Scope *findRecordInNestedList(const std::string & name, bool isC = false); @@ -1199,12 +1205,6 @@ class CPPCHECKLIB Scope { void getVariableList(const Settings& settings, const Token *start, const Token *end); }; -enum class Reference : std::uint8_t { - None, - LValue, - RValue -}; - /** Value type */ class CPPCHECKLIB ValueType { public: diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 0e96c605799..83e02c205e6 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -519,6 +519,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(findFunction53); TEST_CASE(findFunction54); TEST_CASE(findFunction55); // #31004 + TEST_CASE(findFunctionRef1); TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionGlobalScope); // ::foo @@ -8329,6 +8330,25 @@ class TestSymbolDatabase : public TestFixture { ASSERT(Token::simpleMatch(f->function()->tokenDef, "f ( const Token * ptr ) ;")); } + void findFunctionRef1() { + GET_SYMBOL_DB("struct X {\n" + " const std::vector getInts() const & { return mInts; }\n" + " std::vector getInts() && { return mInts; }\n" + " std::vector mInts;\n" + "}\n" + "\n" + "void foo(X &x) {\n" + " x.getInts();\n" + "}\n"); + const Token* x = Token::findsimplematch(tokenizer.tokens(), "x . getInts ( ) ;"); + ASSERT(x); + const Token* f = x->tokAt(2); + ASSERT(f); + ASSERT(f->function()); + ASSERT(f->function()->tokenDef); + ASSERT_EQUALS(2, f->function()->tokenDef->linenr()); + } + void findFunctionContainer() { { GET_SYMBOL_DB("void dostuff(std::vector v);\n"