diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index fdc5deceefa..2c6f72f419c 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -614,8 +614,11 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token } } } - const bool escape = Token::simpleMatch(tok->astParent(), "throw") || - (Token::simpleMatch(tok->astParent(), "return") && !Function::returnsStandardType(scope->function)); + const Token* retThrow = tok->astParent(); + if (Token::simpleMatch(retThrow, "new")) + retThrow = retThrow->astParent(); + const bool escape = Token::simpleMatch(retThrow, "throw") || + (Token::simpleMatch(retThrow, "return") && !Function::returnsStandardType(scope->function)); std::unordered_set exprs; for (const ValueFlow::Value& val:tok->values()) { if (!val.isLocalLifetimeValue() && !val.isSubFunctionLifetimeValue()) diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 2474c2fe6a5..073ab1434d7 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -4062,6 +4062,14 @@ class TestAutoVariables : public TestFixture { " struct S s = { .i = 0, true };\n" "}\n"); // don't crash ASSERT_EQUALS("", errout_str()); + + check("struct A { int& r; };\n" // #14772 + "A* f() {\n" + " int x = 0;\n" + " return new A{ x };\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:19] -> [test.cpp:3:9] -> [test.cpp:4:17]: (error) Returning object that points to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); } void danglingLifetimeInitList() {