Predicate guardNode
Gets a node that controls whether other nodes are evaluated.
In the base case, this is the last node of conditionBlock, and flipped is false.
This definition accounts for (short circuting) and- and or-expressions, as the structure
of basic blocks will reflect their semantics.
However, in the program
if not is_safe(path):
return
the last node in the ConditionBlock is not is_safe(path).
We would like to consider also is_safe(path) a guard node, albeit with flipped being true.
Thus we recurse through not-expressions.
Import path
import semmle.python.dataflow.new.internal.DataFlowPublicControlFlowNode guardNode(ConditionBlock conditionBlock, boolean flipped)