Skip to content

Commit b599e41

Browse files
committed
Fix
1 parent cf0a3b9 commit b599e41

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

‎lib/valueflow.cpp‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,19 @@ ValueFlow::Value ValueFlow::getLifetimeObjValue(const Token *tok, bool inconclus
14731473
return std::move(values.front());
14741474
}
14751475

1476+
static bool checkDotLifetime(const Token* dot, const Token* tok)
1477+
{
1478+
if (Token::simpleMatch(dot->astOperand1(), "."))
1479+
return false;
1480+
if (!dot->astOperand2())
1481+
return true;
1482+
if (dot->astOperand2()->varId() && tok->isUnaryOp("*"))
1483+
return dot->astOperand2()->variable() && dot->astOperand2()->variable()->isArray();
1484+
if (dot->astOperand2()->valueType() && dot->astOperand2()->valueType()->reference != Reference::None)
1485+
return false;
1486+
return true;
1487+
}
1488+
14761489
template<class Predicate>
14771490
static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
14781491
bool escape,
@@ -1585,8 +1598,7 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
15851598
if (vartok->str() == "[" || vartok->isUnaryOp("*"))
15861599
vartok = vartok->astOperand1();
15871600
else if (vartok->str() == ".") {
1588-
if (!Token::simpleMatch(vartok->astOperand1(), ".") &&
1589-
!(vartok->astOperand2() && ((vartok->astOperand2()->varId() && tok->isUnaryOp("*")) || (vartok->astOperand2()->valueType() && vartok->astOperand2()->valueType()->reference != Reference::None))))
1601+
if (checkDotLifetime(vartok, tok))
15901602
vartok = vartok->astOperand1();
15911603
else
15921604
break;

‎test/testautovariables.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4587,6 +4587,17 @@ class TestAutoVariables : public TestFixture {
45874587
" return &*x.a;\n"
45884588
"}\n");
45894589
ASSERT_EQUALS("", errout_str());
4590+
4591+
check("struct S { int a[1]; };\n"
4592+
"int& f(S s) {\n"
4593+
" return *s.a;\n"
4594+
"}\n"
4595+
"int* g(S s) {\n"
4596+
" return &*s.a;\n"
4597+
"}\n");
4598+
ASSERT_EQUALS("[test.cpp:3:12]: (error) Reference to local variable returned. [returnReference]\n"
4599+
"[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",
4600+
errout_str());
45904601
}
45914602

45924603
void danglingLifetimeClassMemberFunctions()

0 commit comments

Comments
 (0)