Fix issue 9939: False positive: Reference to temporary returned (static variable) (#2840)
This commit is contained in:
parent
b90b87af5b
commit
372161c89b
|
@ -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);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue