diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 3ad7ffe62..4ba725f32 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2998,7 +2998,9 @@ std::vector getLifetimeTokens(const Token* tok, bool escape, Valu } else if (Token::simpleMatch(var->declEndToken(), "=")) { errorPath.emplace_back(var->declEndToken(), "Assigned to reference."); const Token *vartok = var->declEndToken()->astOperand2(); - if (vartok == tok || (!escape && var->isConst() && isTemporary(true, vartok, nullptr, true))) + const bool temporary = isTemporary(true, vartok, nullptr, true); + const bool nonlocal = var->isStatic() || var->isGlobal(); + if (vartok == tok || (nonlocal && temporary) || (!escape && var->isConst() && temporary)) return {{tok, true, std::move(errorPath)}}; if (vartok) return getLifetimeTokens(vartok, escape, std::move(errorPath), depth - 1); diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 5dabd4be0..974254f28 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -127,6 +127,7 @@ private: TEST_CASE(extendedLifetime); TEST_CASE(danglingReference); + TEST_CASE(danglingTempReference); // global namespace TEST_CASE(testglobalnamespace); @@ -1745,7 +1746,7 @@ private: " const auto& str_cref2 = g(std::string(\"hello\"));\n" " std::cout << str_cref2 << std::endl;\n" "}\n"); - ASSERT_EQUALS("error", errout.str()); + ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:1] -> [test.cpp:2] -> [test.cpp:5] -> [test.cpp:6]: (error) Using reference to dangling temporary.\n", errout.str()); // Lifetime extended check("std::string g(const std::string& str_cref) {\n" @@ -2859,6 +2860,12 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:5]: (error) Reference to temporary returned.\n", errout.str()); + + check("const std::string& getState() {\n" + " static const std::string& state = \"\";\n" + " return state;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void invalidLifetime() {