@@ -595,14 +595,42 @@ ControlFlowNode guardNode(ConditionBlock conditionBlock, boolean flipped) {
595595 result = conditionBlock .getLastNode ( ) and
596596 flipped = false
597597 or
598- // Recursive case: if a guard node is a `not`-expression,
598+ // Recursive cases:
599+ // if a guard node is a `not`-expression,
599600 // the operand is also a guard node, but with inverted polarity.
600601 exists ( UnaryExprNode notNode |
601602 result = notNode .getOperand ( ) and
602603 notNode .getNode ( ) .getOp ( ) instanceof Not
603604 |
604605 notNode = guardNode ( conditionBlock , flipped .booleanNot ( ) )
605606 )
607+ or
608+ // if a guard node is compared to a boolean literal,
609+ // the other operand is also a guard node,
610+ // but with polarity depending on the literal (and on the comparison).
611+ exists ( CompareNode cmpNode , Cmpop op , ControlFlowNode b , boolean should_flip |
612+ (
613+ cmpNode .operands ( result , op , b ) or
614+ cmpNode .operands ( b , op , result )
615+ ) and
616+ not result .getNode ( ) instanceof BooleanLiteral and
617+ (
618+ // comparing to the boolean
619+ ( op instanceof Eq or op instanceof Is ) and
620+ // we should flip if the value compared against, here the value of `b`, is false
621+ should_flip = b .getNode ( ) .( BooleanLiteral ) .booleanValue ( ) .booleanNot ( )
622+ or
623+ // comparing to the negation of the boolean
624+ ( op instanceof NotEq or op instanceof IsNot ) and
625+ // again, we should flip if the value compared against, here the value of `not b`, is false.
626+ // That is, if the value of `b` is true.
627+ should_flip = b .getNode ( ) .( BooleanLiteral ) .booleanValue ( )
628+ )
629+ |
630+ // we flip `flipped` according to `should_flip` via the formula `flipped xor should_flip`.
631+ flipped in [ true , false ] and
632+ cmpNode = guardNode ( conditionBlock , flipped .booleanXor ( should_flip ) )
633+ )
606634}
607635
608636/**
0 commit comments