From 5cf2f7e633d65188e52b7f878b7b8fc66f0068fe Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Fri, 9 Apr 2021 00:44:20 -0500 Subject: [PATCH] Fix issue 10087: false positive: error: Reference to temporary returned. (#3205) --- lib/symboldatabase.cpp | 13 +++++++------ test/testsymboldatabase.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) 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"