@@ -884,17 +884,38 @@ class ForNode extends ControlFlowNode {
884884
885885 override For getNode ( ) { result = super .getNode ( ) }
886886
887- /** Whether this `for` statement causes iteration over `sequence` storing each step of the iteration in `target` */
887+ /** Holds if this `for` statement causes iteration over `sequence` storing each step of the iteration in `target` */
888888 predicate iterates ( ControlFlowNode target , ControlFlowNode sequence ) {
889+ sequence = getSequence ( ) and
890+ target = possibleTarget ( ) and
891+ not target = unrolledSuffix ( ) .possibleTarget ( )
892+ }
893+
894+ /** Gets the sequence node for this `for` statement. */
895+ ControlFlowNode getSequence ( ) {
896+ exists ( For for |
897+ toAst ( this ) = for and
898+ for .getIter ( ) = result .getNode ( ) |
899+ result .getBasicBlock ( ) .dominates ( this .getBasicBlock ( ) )
900+ )
901+ }
902+
903+ /** A possible `target` for this `for` statement, not accounting for loop unrolling */
904+ private ControlFlowNode possibleTarget ( ) {
889905 exists ( For for |
890906 toAst ( this ) = for and
891- for .getTarget ( ) = target .getNode ( ) and
892- for .getIter ( ) = sequence .getNode ( ) |
893- sequence .getBasicBlock ( ) .dominates ( this .getBasicBlock ( ) ) and
894- sequence .getBasicBlock ( ) .dominates ( target .getBasicBlock ( ) )
907+ for .getTarget ( ) = result .getNode ( ) and
908+ this .getBasicBlock ( ) .dominates ( result .getBasicBlock ( ) )
895909 )
896910 }
897911
912+ /** The unrolled `for` statement node matching this one */
913+ private ForNode unrolledSuffix ( ) {
914+ not this = result and
915+ toAst ( this ) = toAst ( result ) and
916+ this .getBasicBlock ( ) .dominates ( result .getBasicBlock ( ) )
917+ }
918+
898919}
899920
900921/** A flow node for a `raise` statement */
0 commit comments