From 8bf5ae7cd77826da7f4e9b7ba48ee2be40dea2ea Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 29 Oct 2026 13:37:01 +0100 Subject: [PATCH 1/3] Update valueflow.cpp --- lib/valueflow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 4be7a13dbc7..bd4562f7036 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1586,7 +1586,7 @@ static std::vector 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)))) vartok = vartok->astOperand1(); else break; From cf0a3b9a23b1edb37b4a870125f8b72945ab9049 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 29 Oct 2026 13:38:03 +0100 Subject: [PATCH 2/3] Update testautovariables.cpp --- test/testautovariables.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index a2fa4168ea8..2463bc29190 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -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() From b599e414d4dffc7943fa64c7b873f709b41cef4c Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Tue, 3 Nov 2026 22:35:30 +0100 Subject: [PATCH 3/3] Fix --- lib/valueflow.cpp | 16 ++++++++++++++-- test/testautovariables.cpp | 11 +++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index bd4562f7036..fc5e103172a 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1473,6 +1473,19 @@ ValueFlow::Value ValueFlow::getLifetimeObjValue(const Token *tok, bool inconclus return std::move(values.front()); } +static bool checkDotLifetime(const Token* dot, const Token* tok) +{ + if (Token::simpleMatch(dot->astOperand1(), ".")) + return false; + if (!dot->astOperand2()) + return true; + if (dot->astOperand2()->varId() && tok->isUnaryOp("*")) + return dot->astOperand2()->variable() && dot->astOperand2()->variable()->isArray(); + if (dot->astOperand2()->valueType() && dot->astOperand2()->valueType()->reference != Reference::None) + return false; + return true; +} + template static std::vector getLifetimeTokens(const Token* tok, bool escape, @@ -1585,8 +1598,7 @@ static std::vector getLifetimeTokens(const Token* tok, if (vartok->str() == "[" || vartok->isUnaryOp("*")) vartok = vartok->astOperand1(); else if (vartok->str() == ".") { - if (!Token::simpleMatch(vartok->astOperand1(), ".") && - !(vartok->astOperand2() && ((vartok->astOperand2()->varId() && tok->isUnaryOp("*")) || (vartok->astOperand2()->valueType() && vartok->astOperand2()->valueType()->reference != Reference::None)))) + if (checkDotLifetime(vartok, tok)) vartok = vartok->astOperand1(); else break; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 2463bc29190..d5ab5855c32 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -4587,6 +4587,17 @@ class TestAutoVariables : public TestFixture { " return &*x.a;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S { int a[1]; };\n" + "int& f(S s) {\n" + " return *s.a;\n" + "}\n" + "int* g(S s) {\n" + " return &*s.a;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:12]: (error) Reference to local variable returned. [returnReference]\n" + "[test.cpp:6:12] -> [test.cpp:5:10] -> [test.cpp:6:12]: (error) Returning pointer to local variable 's' that will be invalid when returning. [returnDanglingLifetime]\n", + errout_str()); } void danglingLifetimeClassMemberFunctions()