Skip to content

Commit 422e3d0

Browse files
Fix #15087 FP constParameterReference (returning reference to member in ternary) (#8918)
1 parent 5114436 commit 422e3d0

2 files changed

Lines changed: 36 additions & 12 deletions

File tree

‎lib/checkother.cpp‎

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,18 +1828,31 @@ void CheckOtherImpl::checkConstVariable()
18281828
if (function && (Function::returnsReference(function) || Function::returnsPointer(function)) && !Function::returnsConst(function)) {
18291829
std::vector<const Token*> returns = Function::findReturns(function);
18301830
if (std::any_of(returns.cbegin(), returns.cend(), [&](const Token* retTok) {
1831-
if (retTok->varId() == var->declarationId())
1832-
return true;
1833-
while (retTok && retTok->isCast())
1834-
retTok = retTok->astOperand2() ? retTok->astOperand2() : retTok->astOperand1();
1835-
while (Token::simpleMatch(retTok, "."))
1836-
retTok = retTok->astOperand2();
1837-
if (Token::simpleMatch(retTok, "&"))
1838-
retTok = retTok->astOperand1();
1839-
ValueFlow::Value ltVal = ValueFlow::getLifetimeObjValue(retTok);
1840-
if (ltVal.isLifetimeValue() && ltVal.tokvalue->varId() == var->declarationId())
1841-
return true;
1842-
return ValueFlow::hasLifetimeToken(getParentLifetime(retTok), var->nameToken(), mSettings);
1831+
bool result = false;
1832+
visitAstNodes(retTok, [&result, &var, this](const Token* tok) {
1833+
if (tok->varId() == var->declarationId()) {
1834+
result = true;
1835+
return ChildrenToVisit::done;
1836+
}
1837+
ValueFlow::Value ltVal = ValueFlow::getLifetimeObjValue(tok);
1838+
if ((ltVal.isLifetimeValue() && ltVal.tokvalue->varId() == var->declarationId()) ||
1839+
ValueFlow::hasLifetimeToken(getParentLifetime(tok), var->nameToken(), mSettings)) {
1840+
result = true;
1841+
return ChildrenToVisit::done;
1842+
}
1843+
if (tok->isCast())
1844+
return tok->astOperand2() ? ChildrenToVisit::op2 : ChildrenToVisit::op1;
1845+
if (tok->str() == ".")
1846+
return ChildrenToVisit::op2;
1847+
if (tok->str() == "&")
1848+
return ChildrenToVisit::op1;
1849+
if (tok->str() == "?")
1850+
return ChildrenToVisit::op2;
1851+
if (tok->str() == ":")
1852+
return ChildrenToVisit::op1_and_op2;
1853+
return ChildrenToVisit::none;
1854+
});
1855+
return result;
18431856
}))
18441857
continue;
18451858
}

‎test/testother.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4238,6 +4238,17 @@ class TestOther : public TestFixture {
42384238
"using FR = int&(&)();\n"
42394239
"void f6(FR f) { f(); }\n");
42404240
ASSERT_EQUALS("", errout_str());
4241+
4242+
check("struct S {\n" // #15087
4243+
" int a, b;\n"
4244+
"};\n"
4245+
"int& f(S& s, bool b) {\n"
4246+
" return b ? s.a : s.b;\n"
4247+
"}\n"
4248+
"int* g(U& u) {\n"
4249+
" return &(u.i);\n"
4250+
"}\n");
4251+
ASSERT_EQUALS("", errout_str());
42414252
}
42424253

42434254
void constParameterCallback() {

0 commit comments

Comments
 (0)