Skip to content

Commit 30f2bb7

Browse files
committed
ValueFlow: set known value for opposite condition in else if (#5503)
1 parent 112b35a commit 30f2bb7

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

lib/valueflow.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,36 @@ static void valueFlowBitAnd(TokenList *tokenlist)
713713
}
714714
}
715715

716+
static void valueFlowOppositeCondition(SymbolDatabase *symboldatabase, const Settings *settings)
717+
{
718+
for (std::list<Scope>::iterator scope = symboldatabase->scopeList.begin(); scope != symboldatabase->scopeList.end(); ++scope) {
719+
if (scope->type != Scope::eIf)
720+
continue;
721+
Token *tok = const_cast<Token *>(scope->classDef);
722+
if (!Token::Match(tok, "if ("))
723+
continue;
724+
const Token *cond1 = tok->next()->astOperand2();
725+
if (!cond1 || !cond1->isComparisonOp())
726+
continue;
727+
const bool cpp = symboldatabase->isCPP();
728+
Token *tok2 = tok->linkAt(1);
729+
while (Token::simpleMatch(tok2, ") {")) {
730+
tok2 = tok2->linkAt(1);
731+
if (!Token::simpleMatch(tok2, "} else { if ("))
732+
break;
733+
const Token *cond2 = tok2->tokAt(4)->astOperand2();
734+
if (!cond2 || !cond2->isComparisonOp())
735+
continue;
736+
if (isOppositeCond(false, cpp, cond1, cond2, settings->library.functionpure)) {
737+
ValueFlow::Value value(1);
738+
value.setKnown();
739+
setTokenValue(const_cast<Token*>(cond2), value);
740+
}
741+
tok2 = tok2->linkAt(4);
742+
}
743+
}
744+
}
745+
716746
static void valueFlowReverse(TokenList *tokenlist,
717747
Token *tok,
718748
const Token * const varToken,
@@ -2341,6 +2371,7 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase,
23412371
valueFlowPointerAlias(tokenlist);
23422372
valueFlowFunctionReturn(tokenlist, errorLogger, settings);
23432373
valueFlowBitAnd(tokenlist);
2374+
valueFlowOppositeCondition(symboldatabase, settings);
23442375
valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings);
23452376
valueFlowBeforeCondition(tokenlist, symboldatabase, errorLogger, settings);
23462377
valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings);

test/testvalueflow.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,14 @@ class TestValueFlow : public TestFixture {
18891889
ASSERT_EQUALS(5, value.intvalue);
18901890
ASSERT(value.isPossible());
18911891

1892+
code = "int f(int x) {\n"
1893+
" if (x < 2) {}\n"
1894+
" else if (x >= 2) {}\n" // <- known value
1895+
"}";
1896+
value = valueOfTok(code, ">=");
1897+
ASSERT_EQUALS(1, value.intvalue);
1898+
ASSERT(value.isKnown());
1899+
18921900
// function
18931901
code = "int f(int x) { return x + 1; }\n" // <- possible value
18941902
"void a() { f(12); }\b";

0 commit comments

Comments
 (0)