@@ -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+
716746static 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);
0 commit comments