This commit is contained in:
parent
4cb49013a7
commit
665e4230f2
|
@ -578,7 +578,8 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const bool escape = Token::Match(tok->astParent(), "return|throw");
|
const bool escape = Token::simpleMatch(tok->astParent(), "throw") ||
|
||||||
|
(Token::simpleMatch(tok->astParent(), "return") && !Function::returnsStandardType(scope->function));
|
||||||
std::unordered_set<const Token*> exprs;
|
std::unordered_set<const Token*> exprs;
|
||||||
for (const ValueFlow::Value& val:tok->values()) {
|
for (const ValueFlow::Value& val:tok->values()) {
|
||||||
if (!val.isLocalLifetimeValue() && !val.isSubFunctionLifetimeValue())
|
if (!val.isLocalLifetimeValue() && !val.isSubFunctionLifetimeValue())
|
||||||
|
|
|
@ -2931,6 +2931,13 @@ bool Function::returnsReference(const Function* function, bool unknown)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Function::returnsStandardType(const Function* function, bool unknown)
|
||||||
|
{
|
||||||
|
return checkReturns(function, unknown, true, [](UNUSED const Token* defStart, const Token* defEnd) {
|
||||||
|
return defEnd->previous() && defEnd->previous()->isStandardType();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool Function::returnsVoid(const Function* function, bool unknown)
|
bool Function::returnsVoid(const Function* function, bool unknown)
|
||||||
{
|
{
|
||||||
return checkReturns(function, unknown, true, [](UNUSED const Token* defStart, const Token* defEnd) {
|
return checkReturns(function, unknown, true, [](UNUSED const Token* defStart, const Token* defEnd) {
|
||||||
|
|
|
@ -930,6 +930,7 @@ public:
|
||||||
static bool returnsConst(const Function* function, bool unknown = false);
|
static bool returnsConst(const Function* function, bool unknown = false);
|
||||||
|
|
||||||
static bool returnsReference(const Function* function, bool unknown = false);
|
static bool returnsReference(const Function* function, bool unknown = false);
|
||||||
|
static bool returnsStandardType(const Function* function, bool unknown = false);
|
||||||
|
|
||||||
static bool returnsVoid(const Function* function, bool unknown = false);
|
static bool returnsVoid(const Function* function, bool unknown = false);
|
||||||
|
|
||||||
|
|
|
@ -2768,6 +2768,22 @@ private:
|
||||||
ASSERT_EQUALS(
|
ASSERT_EQUALS(
|
||||||
"[test.cpp:2] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning pointer to local variable 'p' that will be invalid when returning.\n",
|
"[test.cpp:2] -> [test.cpp:1] -> [test.cpp:3]: (error) Returning pointer to local variable 'p' that will be invalid when returning.\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
|
check("int* f();\n" // #11406
|
||||||
|
"bool g() {\n"
|
||||||
|
" std::unique_ptr<int> ptr(f());\n"
|
||||||
|
" return ptr.get();\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("int* f();\n"
|
||||||
|
"int* g() {\n"
|
||||||
|
" std::unique_ptr<int> ptr(f());\n"
|
||||||
|
" return ptr.get();\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS(
|
||||||
|
"[test.cpp:4] -> [test.cpp:3] -> [test.cpp:4]: (error) Returning object that points to local variable 'ptr' that will be invalid when returning.\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
void danglingLifetime() {
|
void danglingLifetime() {
|
||||||
check("auto f() {\n"
|
check("auto f() {\n"
|
||||||
|
|
Loading…
Reference in New Issue