From 196f25725011a6a6f9eef7fce70df2b6f3ec8d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 20 Nov 2024 16:31:10 +0000 Subject: [PATCH] Fix #13328 (SymbolDatabase: does not select l-value method properly) (#7026) (cherry picked from c3074830d5406b1c5ee7a058a0146cb770f39087) --- lib/symboldatabase.cpp | 11 +++++++++++ test/testsymboldatabase.cpp | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 31a42608ff4..d7c48997bd6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5716,6 +5716,17 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst, Referen const Function *func = it->second; if (ref == Reference::LValue && func->hasRvalRefQualifier()) continue; + if (ref == Reference::None && func->hasRvalRefQualifier()) { + if (Token::simpleMatch(tok->astParent(), ".")) { + const Token* obj = tok->astParent()->astOperand1(); + while (obj && obj->str() == "[") + obj = obj->astOperand1(); + if (!obj || obj->isName()) + continue; + } + } + if (func->isDestructor() && !Token::simpleMatch(tok->tokAt(-1), "~")) + continue; if (!isCall || args == func->argCount() || (func->isVariadic() && args >= (func->minArgCount() - 1)) || (args < func->argCount() && args >= func->minArgCount())) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 84394e491e2..2935c556bd1 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -521,6 +521,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(findFunction55); // #13004 TEST_CASE(findFunction56); TEST_CASE(findFunctionRef1); + TEST_CASE(findFunctionRef2); // #13328 TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionGlobalScope); // ::foo @@ -8368,6 +8369,25 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(2, f->function()->tokenDef->linenr()); } + void findFunctionRef2() { + GET_SYMBOL_DB("struct X {\n" + " const int& foo() const &;\n" // <- this function is called + " int foo() &&;\n" + "}\n" + "\n" + "void foo() {\n" + " X x;\n" + " x.foo();\n" + "}\n"); + const Token* x = Token::findsimplematch(tokenizer.tokens(), "x . foo ( ) ;"); + 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"