From 83876088f9ed4a76967e2bea751be42525b636d1 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 5 Oct 2026 09:50:08 +0200 Subject: [PATCH 1/3] Update testother.cpp --- test/testother.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/testother.cpp b/test/testother.cpp index 0d2993d0668..27f10258559 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4201,6 +4201,14 @@ class TestOther : public TestFixture { " }\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" // #15087 + " int a, b;\n" + "};\n" + "int& f(S& s, bool b) {\n" + " return b ? s.a : s.b;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void constParameterCallback() { From 9de5bdd18784d29857cc6bcffbb215c0658ef614 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 5 Oct 2026 09:52:13 +0200 Subject: [PATCH 2/3] Update checkother.cpp --- lib/checkother.cpp | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index c229cfed789..430a20c00ac 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1810,18 +1810,33 @@ void CheckOtherImpl::checkConstVariable() if (function && (Function::returnsReference(function) || Function::returnsPointer(function)) && !Function::returnsConst(function)) { std::vector returns = Function::findReturns(function); if (std::any_of(returns.cbegin(), returns.cend(), [&](const Token* retTok) { - if (retTok->varId() == var->declarationId()) - return true; - while (retTok && retTok->isCast()) - retTok = retTok->astOperand2() ? retTok->astOperand2() : retTok->astOperand1(); - while (Token::simpleMatch(retTok, ".")) - retTok = retTok->astOperand2(); - if (Token::simpleMatch(retTok, "&")) - retTok = retTok->astOperand1(); - ValueFlow::Value ltVal = ValueFlow::getLifetimeObjValue(retTok); - if (ltVal.isLifetimeValue() && ltVal.tokvalue->varId() == var->declarationId()) - return true; - return ValueFlow::hasLifetimeToken(getParentLifetime(retTok), var->nameToken(), mSettings); + bool result = false; + visitAstNodes(retTok, [&result, &var, this](const Token* tok) { + if (tok->varId() == var->declarationId()) { + result = true; + return ChildrenToVisit::done; + } + if (tok->isCast()) + return tok->astOperand2() ? ChildrenToVisit::op2 : ChildrenToVisit::op1; + if (tok->str() == ".") + return ChildrenToVisit::op2; + if (tok->str() == "&") + return ChildrenToVisit::op1; + if (tok->str() == "?") + return ChildrenToVisit::op2; + if (tok->str() == ":") + return ChildrenToVisit::op1_and_op2; + + ValueFlow::Value ltVal = ValueFlow::getLifetimeObjValue(tok); + if ((ltVal.isLifetimeValue() && ltVal.tokvalue->varId() == var->declarationId()) || + ValueFlow::hasLifetimeToken(getParentLifetime(tok), var->nameToken(), mSettings)) { + result = true; + return ChildrenToVisit::done; + } + return ChildrenToVisit::none; + }); + return result; + })) continue; } From a32896bae9cdbea6635e03d6c411ee440826e4e7 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 5 Oct 2026 10:17:12 +0200 Subject: [PATCH 3/3] Format --- lib/checkother.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 430a20c00ac..10ba68b819a 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1823,20 +1823,19 @@ void CheckOtherImpl::checkConstVariable() if (tok->str() == "&") return ChildrenToVisit::op1; if (tok->str() == "?") - return ChildrenToVisit::op2; + return ChildrenToVisit::op2; if (tok->str() == ":") - return ChildrenToVisit::op1_and_op2; + return ChildrenToVisit::op1_and_op2; ValueFlow::Value ltVal = ValueFlow::getLifetimeObjValue(tok); - if ((ltVal.isLifetimeValue() && ltVal.tokvalue->varId() == var->declarationId()) || + if ((ltVal.isLifetimeValue() && ltVal.tokvalue->varId() == var->declarationId()) || ValueFlow::hasLifetimeToken(getParentLifetime(tok), var->nameToken(), mSettings)) { result = true; return ChildrenToVisit::done; } return ChildrenToVisit::none; - }); + }); return result; - })) continue; }