diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 41498ae58..e6215d21f 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6830,20 +6830,27 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va return ValueType::MatchResult::UNKNOWN; // TODO } - if (call->typeScope != nullptr || func->typeScope != nullptr) - return call->typeScope == func->typeScope ? ValueType::MatchResult::SAME : ValueType::MatchResult::NOMATCH; + if (call->typeScope != nullptr || func->typeScope != nullptr) { + if (call->typeScope != func->typeScope) + return ValueType::MatchResult::NOMATCH; + } if (call->container != nullptr || func->container != nullptr) { if (call->container != func->container) return ValueType::MatchResult::NOMATCH; } - else if (func->type < ValueType::Type::VOID || func->type == ValueType::Type::UNKNOWN_INT) - return ValueType::MatchResult::UNKNOWN; + if (func->typeScope != nullptr && func->container != nullptr) { + if (func->type < ValueType::Type::VOID || func->type == ValueType::Type::UNKNOWN_INT) + return ValueType::MatchResult::UNKNOWN; + } if (call->isIntegral() && func->isIntegral() && call->sign != ValueType::Sign::UNKNOWN_SIGN && func->sign != ValueType::Sign::UNKNOWN_SIGN && call->sign != func->sign) return ValueType::MatchResult::FALLBACK1; + if (func->reference != Reference::None && func->constness > call->constness) + return ValueType::MatchResult::FALLBACK1; + return ValueType::MatchResult::SAME; } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index fd3286e97..3d6062d7d 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -405,6 +405,8 @@ private: TEST_CASE(findFunction38); // #10125 TEST_CASE(findFunction39); // #10127 TEST_CASE(findFunction40); // #10135 + TEST_CASE(findFunction41); // #10202 + TEST_CASE(findFunction42); TEST_CASE(findFunctionContainer); TEST_CASE(findFunctionExternC); TEST_CASE(findFunctionGlobalScope); // ::foo @@ -6378,6 +6380,51 @@ private: ASSERT_EQUALS(3, functok->function()->tokenDef->linenr()); } + void findFunction41() { // #10202 + { + GET_SYMBOL_DB("struct A {};\n" + "const int* g(const A&);\n" + "int* g(A&);\n" + "void f(A& x) {\n" + " int* y = g(x);\n" + " *y = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + const Token *functok = Token::findsimplematch(tokenizer.tokens(), "g ( x )"); + ASSERT(functok); + ASSERT(functok->function()); + ASSERT(functok->function()->name() == "g"); + ASSERT_EQUALS(3, functok->function()->tokenDef->linenr()); + } + { + GET_SYMBOL_DB("struct A {};\n" + "const int* g(const A&);\n" + "int* g(A&);\n" + "void f(const A& x) {\n" + " int* y = g(x);\n" + " *y = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + const Token *functok = Token::findsimplematch(tokenizer.tokens(), "g ( x )"); + ASSERT(functok); + ASSERT(functok->function()); + ASSERT(functok->function()->name() == "g"); + ASSERT_EQUALS(2, functok->function()->tokenDef->linenr()); + } + } + + void findFunction42() { + GET_SYMBOL_DB("void a(const std::string &, const std::string &);\n" + "void a(long, long);\n" + "void b() { a(true, false); }\n"); + ASSERT_EQUALS("", errout.str()); + const Token *functok = Token::findsimplematch(tokenizer.tokens(), "a ( true , false )"); + ASSERT(functok); + ASSERT(functok->function()); + ASSERT(functok->function()->name() == "a"); + ASSERT_EQUALS(2, functok->function()->tokenDef->linenr()); + } + void findFunctionContainer() { { GET_SYMBOL_DB("void dostuff(std::vector v);\n"