Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1586,7 +1586,7 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
vartok = vartok->astOperand1();
else if (vartok->str() == ".") {
if (!Token::simpleMatch(vartok->astOperand1(), ".") &&
!(vartok->astOperand2() && vartok->astOperand2()->valueType() && vartok->astOperand2()->valueType()->reference != Reference::None))
!(vartok->astOperand2() && ((vartok->astOperand2()->varId() && tok->isUnaryOp("*")) || (vartok->astOperand2()->valueType() && vartok->astOperand2()->valueType()->reference != Reference::None))))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review

varId() && tok->isUnaryOp("*") is true for array members too, and there dereferencing gives an element of the local object. Example: struct S { int a[10]; }; int* f() { S s; return &*s.a; } and int& f() { S s{}; return *s.a; }. Both were reported before (returnDanglingLifetime / returnReference) and are silent with this PR. The same happens for &*s.b[0] with int b[3][3]. Consider checking that the member is a real pointer, e.g. vt && vt->pointer > 0 && !(var && var->isArray()), and add tests for the array cases.

vartok = vartok->astOperand1();
else
break;
Expand Down
6 changes: 6 additions & 0 deletions test/testautovariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4581,6 +4581,12 @@ class TestAutoVariables : public TestFixture {
ASSERT_EQUALS("[test.cpp:5:11] -> [test.cpp:4:9] -> [test.cpp:5:6]: (error) Non-local variable 'g.a' will use pointer to local variable 'x'. [danglingLifetime]\n"
"[test.cpp:5:11] -> [test.cpp:4:9] -> [test.cpp:6:13]: (error) Returning pointer to local variable 'x' that will be invalid when returning. [returnDanglingLifetime]\n",
errout_str());

check("int* f() {\n" // #11168
" auto x = get();\n"
" return &*x.a;\n"
"}\n");
ASSERT_EQUALS("", errout_str());
}

void danglingLifetimeClassMemberFunctions()
Expand Down
Loading