Fix issue 9595: False positive: Using pointer to temporary doesn't account for const ref extended temporary lifetimes (#2525)
This commit is contained in:
parent
125c4832cd
commit
8fa7dd0fe0
|
@ -220,7 +220,7 @@ const Token * astIsVariableComparison(const Token *tok, const std::string &comp,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTemporary(bool cpp, const Token* tok, const Library* library)
|
bool isTemporary(bool cpp, const Token* tok, const Library* library, bool unknown)
|
||||||
{
|
{
|
||||||
if (!tok)
|
if (!tok)
|
||||||
return false;
|
return false;
|
||||||
|
@ -251,7 +251,7 @@ bool isTemporary(bool cpp, const Token* tok, const Library* library)
|
||||||
std::string returnType = library->returnValueType(ftok);
|
std::string returnType = library->returnValueType(ftok);
|
||||||
return !returnType.empty() && returnType.back() != '&';
|
return !returnType.empty() && returnType.back() != '&';
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -87,7 +87,7 @@ std::string astCanonicalType(const Token *expr);
|
||||||
/** Is given syntax tree a variable comparison against value */
|
/** Is given syntax tree a variable comparison against value */
|
||||||
const Token * astIsVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok=nullptr);
|
const Token * astIsVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok=nullptr);
|
||||||
|
|
||||||
bool isTemporary(bool cpp, const Token* tok, const Library* library);
|
bool isTemporary(bool cpp, const Token* tok, const Library* library, bool unknown = false);
|
||||||
|
|
||||||
const Token * nextAfterAstRightmostLeaf(const Token * tok);
|
const Token * nextAfterAstRightmostLeaf(const Token * tok);
|
||||||
|
|
||||||
|
|
|
@ -3231,7 +3231,7 @@ std::vector<LifetimeToken> getLifetimeTokens(const Token* tok, ValueFlow::Value:
|
||||||
} 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 || (var->isConst() && isTemporary(true, vartok, nullptr)))
|
if (vartok == tok || (var->isConst() && isTemporary(true, vartok, nullptr, true)))
|
||||||
return {{tok, true, std::move(errorPath)}};
|
return {{tok, true, std::move(errorPath)}};
|
||||||
if (vartok)
|
if (vartok)
|
||||||
return getLifetimeTokens(vartok, std::move(errorPath), depth - 1);
|
return getLifetimeTokens(vartok, std::move(errorPath), depth - 1);
|
||||||
|
|
|
@ -2501,6 +2501,13 @@ private:
|
||||||
ASSERT_EQUALS(
|
ASSERT_EQUALS(
|
||||||
"[test.cpp:3] -> [test.cpp:4]: (error) Using iterator to temporary.\n",
|
"[test.cpp:3] -> [test.cpp:4]: (error) Using iterator to temporary.\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
|
check("std::string f() {\n"
|
||||||
|
" std::stringstream tmp;\n"
|
||||||
|
" const std::string &str = tmp.str();\n"
|
||||||
|
" return std::string(str.c_str(), 1);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidLifetime() {
|
void invalidLifetime() {
|
||||||
|
|
Loading…
Reference in New Issue