diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 88cbd0ddc..075cc961f 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -30,6 +30,7 @@ #include "tokenize.h" #include "valueflow.h" +#include #include //--------------------------------------------------------------------------- @@ -434,7 +435,14 @@ static int getPointerDepth(const Token *tok) { if (!tok) return 0; - return tok->valueType() ? tok->valueType()->pointer : 0; + if (tok->valueType()) + return tok->valueType()->pointer; + int n = 0; + std::pair decl = Token::typeDecl(tok); + for (const Token* tok2 = decl.first; tok2 != decl.second; tok2 = tok2->next()) + if (Token::simpleMatch(tok, "*")) + n++; + return n; } static bool isDeadTemporary(bool cpp, const Token* tok, const Token* expr, const Library* library) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 86cbc6498..5cffbe48b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -34,9 +34,10 @@ #include #include #include -#include #include #include +#include +#include #include //--------------------------------------------------------------------------- @@ -6906,7 +6907,12 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va 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) + const bool templateVar = + funcVar->scope() && funcVar->scope()->function && funcVar->scope()->function->templateDef; + if (type1 == type2) + return ValueType::MatchResult::SAME; + if (!templateVar && type1.find("auto") == std::string::npos && type2.find("auto") == std::string::npos && + type1 != type2) return ValueType::MatchResult::NOMATCH; } return res; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c38575bb1..d290cbef2 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2896,6 +2896,8 @@ static bool isLifetimeBorrowed(const ValueType *vt, const ValueType *vtParent) return false; if (!vt) return false; + if (vt->pointer > 0 && vt->pointer == vtParent->pointer) + return true; if (vt->type != ValueType::UNKNOWN_TYPE && vtParent->type != ValueType::UNKNOWN_TYPE && vtParent->container == vt->container) { if (vtParent->pointer > vt->pointer) return true; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 019360380..16ec345a3 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -2146,9 +2146,8 @@ private: " return get_default(m, k, &x);\n" "}\n", true); - TODO_ASSERT_EQUALS( + ASSERT_EQUALS( "[test.cpp:9] -> [test.cpp:9] -> [test.cpp:8] -> [test.cpp:9]: (error, inconclusive) Returning pointer to local variable 'x' that will be invalid when returning.\n", - "", errout.str()); check("std::vector g();\n"