diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp
index e6215d21f..e889be586 100644
--- a/lib/symboldatabase.cpp
+++ b/lib/symboldatabase.cpp
@@ -4818,11 +4818,12 @@ static std::string getTypeString(const Token *typeToken)
while (Token::Match(typeToken, ":: %name%")) {
ret += "::" + typeToken->strAt(1);
typeToken = typeToken->tokAt(2);
- }
- if (typeToken->str() == "<") {
- for (const Token *tok = typeToken; tok != typeToken->link(); tok = tok->next())
- ret += tok->str();
- ret += ">";
+ if (typeToken->str() == "<") {
+ for (const Token *tok = typeToken; tok != typeToken->link(); tok = tok->next())
+ ret += tok->str();
+ ret += ">";
+ typeToken = typeToken->link()->next();
+ }
}
return ret;
}
@@ -6857,7 +6858,7 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va
ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Variable *callVar, const Variable *funcVar)
{
ValueType::MatchResult res = ValueType::matchParameter(call, funcVar->valueType());
- if (res == ValueType::MatchResult::SAME && callVar && call->container) {
+ if (callVar && ((res == ValueType::MatchResult::SAME && call->container) || res == ValueType::MatchResult::UNKNOWN)) {
const std::string type1 = getTypeString(callVar->typeStartToken());
const std::string type2 = getTypeString(funcVar->typeStartToken());
if (type1 != type2)
diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp
index 3d6062d7d..3fcd0518f 100644
--- a/test/testsymboldatabase.cpp
+++ b/test/testsymboldatabase.cpp
@@ -407,6 +407,7 @@ private:
TEST_CASE(findFunction40); // #10135
TEST_CASE(findFunction41); // #10202
TEST_CASE(findFunction42);
+ TEST_CASE(findFunction43); // #10087
TEST_CASE(findFunctionContainer);
TEST_CASE(findFunctionExternC);
TEST_CASE(findFunctionGlobalScope); // ::foo
@@ -6425,6 +6426,34 @@ private:
ASSERT_EQUALS(2, functok->function()->tokenDef->linenr());
}
+ void findFunction43() { // #10087
+ {
+ GET_SYMBOL_DB("struct A {};\n"
+ "const A* g(const std::string&);\n"
+ "const A& g(std::vector::size_type i);\n"
+ "const A& f(std::vector::size_type i) { return g(i); }\n");
+ ASSERT_EQUALS("", errout.str());
+ const Token *functok = Token::findsimplematch(tokenizer.tokens(), "g ( i )");
+ ASSERT(functok);
+ ASSERT(functok->function());
+ ASSERT(functok->function()->name() == "g");
+ ASSERT_EQUALS(3, functok->function()->tokenDef->linenr());
+ }
+ {
+ GET_SYMBOL_DB("struct A {};\n"
+ "const A& g(std::vector::size_type i);\n"
+ "const A* g(const std::string&);\n"
+ "const A& f(std::vector::size_type i) { return g(i); }\n");
+ ASSERT_EQUALS("", errout.str());
+ const Token *functok = Token::findsimplematch(tokenizer.tokens(), "g ( i )");
+ ASSERT(functok);
+ ASSERT(functok->function());
+ ASSERT(functok->function()->name() == "g");
+ ASSERT_EQUALS(2, functok->function()->tokenDef->linenr());
+ }
+ }
+
+
void findFunctionContainer() {
{
GET_SYMBOL_DB("void dostuff(std::vector v);\n"