Fix issue 9939: False positive: Reference to temporary returned (static variable) (#2840)

This commit is contained in:
Paul Fultz II 2020-10-06 02:16:54 -05:00 committed by GitHub
parent b90b87af5b
commit 372161c89b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 2 deletions

View File

@ -2998,7 +2998,9 @@ std::vector<LifetimeToken> getLifetimeTokens(const Token* tok, bool escape, Valu
} else if (Token::simpleMatch(var->declEndToken(), "=")) { } else if (Token::simpleMatch(var->declEndToken(), "=")) {
errorPath.emplace_back(var->declEndToken(), "Assigned to reference."); errorPath.emplace_back(var->declEndToken(), "Assigned to reference.");
const Token *vartok = var->declEndToken()->astOperand2(); 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)}}; return {{tok, true, std::move(errorPath)}};
if (vartok) if (vartok)
return getLifetimeTokens(vartok, escape, std::move(errorPath), depth - 1); return getLifetimeTokens(vartok, escape, std::move(errorPath), depth - 1);

View File

@ -127,6 +127,7 @@ private:
TEST_CASE(extendedLifetime); TEST_CASE(extendedLifetime);
TEST_CASE(danglingReference); TEST_CASE(danglingReference);
TEST_CASE(danglingTempReference);
// global namespace // global namespace
TEST_CASE(testglobalnamespace); TEST_CASE(testglobalnamespace);
@ -1745,7 +1746,7 @@ private:
" const auto& str_cref2 = g(std::string(\"hello\"));\n" " const auto& str_cref2 = g(std::string(\"hello\"));\n"
" std::cout << str_cref2 << std::endl;\n" " std::cout << str_cref2 << std::endl;\n"
"}\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 // Lifetime extended
check("std::string g(const std::string& str_cref) {\n" check("std::string g(const std::string& str_cref) {\n"
@ -2859,6 +2860,12 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:5]: (error) Reference to temporary returned.\n", ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3] -> [test.cpp:5]: (error) Reference to temporary returned.\n",
errout.str()); errout.str());
check("const std::string& getState() {\n"
" static const std::string& state = \"\";\n"
" return state;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void invalidLifetime() { void invalidLifetime() {