11import python
22import semmle.python.flow.NameNode
33private import semmle.python.pointsto.PointsTo
4- private import semmle.python.Pruning
54
65/* Note about matching parent and child nodes and CFG splitting:
76 *
@@ -33,10 +32,6 @@ private AstNode toAst(ControlFlowNode n) {
3332*/
3433class ControlFlowNode extends @py_flow_node {
3534
36- cached ControlFlowNode ( ) {
37- Pruner:: reachable ( this )
38- }
39-
4035 /** Whether this control flow node is a load (including those in augmented assignments) */
4136 predicate isLoad ( ) {
4237 exists ( Expr e | e = toAst ( this ) | py_expr_contexts ( _, 3 , e ) and not augstore ( _, this ) )
@@ -180,8 +175,7 @@ class ControlFlowNode extends @py_flow_node {
180175
181176 /** Gets a successor of this flow node */
182177 ControlFlowNode getASuccessor ( ) {
183- py_successors ( this , result ) and
184- not Pruner:: unreachableEdge ( this , result )
178+ py_successors ( this , result )
185179 }
186180
187181 /** Gets the immediate dominator of this flow node */
@@ -973,91 +967,21 @@ predicate defined_by(NameNode def, Variable v) {
973967 exists ( NameNode p | defined_by ( p , v ) and p .getASuccessor ( ) = def and not p .defines ( v ) )
974968}
975969
976- /* Combine extractor-generated basic block after pruning */
977-
978- private class BasicBlockPart extends @py_flow_node {
979-
980- string toString ( ) { result = "Basic block part" }
981-
982- BasicBlockPart ( ) {
983- py_flow_bb_node ( _, _, this , _) and
984- Pruner:: reachable ( this )
985- }
986-
987- predicate isHead ( ) {
988- count ( this .( ControlFlowNode ) .getAPredecessor ( ) ) != 1
989- or
990- exists ( ControlFlowNode pred | pred = this .( ControlFlowNode ) .getAPredecessor ( ) | strictcount ( pred .getASuccessor ( ) ) > 1 )
991- }
992-
993- private BasicBlockPart previous ( ) {
994- not this .isHead ( ) and
995- py_flow_bb_node ( this .( ControlFlowNode ) .getAPredecessor ( ) , _, result , _)
996- }
997-
998- BasicBlockPart getHead ( ) {
999- this .isHead ( ) and result = this
1000- or
1001- result = this .previous ( ) .getHead ( )
1002- }
1003-
1004- predicate isLast ( ) {
1005- not exists ( BasicBlockPart part | part .previous ( ) = this )
1006- }
1007-
1008- int length ( ) {
1009- result = max ( int j | py_flow_bb_node ( _, _, this , j ) ) + 1
1010- }
1011-
1012- int startIndex ( ) {
1013- this .isHead ( ) and result = 0
1014- or
1015- exists ( BasicBlockPart prev |
1016- prev = this .previous ( ) and
1017- result = prev .startIndex ( ) + prev .length ( )
1018- )
1019- }
1020-
1021- predicate contains ( ControlFlowNode node ) {
1022- py_flow_bb_node ( node , _, this , _)
1023- }
1024-
1025- int indexOf ( ControlFlowNode node ) {
1026- py_flow_bb_node ( node , _, this , result )
1027- }
1028-
1029- ControlFlowNode lastNode ( ) {
1030- this .indexOf ( result ) = max ( this .indexOf ( _) )
1031- }
1032-
1033- BasicBlockPart getImmediateDominator ( ) {
1034- result .contains ( this .( ControlFlowNode ) .getImmediateDominator ( ) )
1035- }
1036-
1037- }
1038-
1039970/** A basic block (ignoring exceptional flow edges to scope exit) */
1040971class BasicBlock extends @py_flow_node {
1041972
1042973 BasicBlock ( ) {
1043- this .( BasicBlockPart ) .isHead ( )
1044- }
1045-
1046- private BasicBlockPart getAPart ( ) {
1047- result .getHead ( ) = this
974+ py_flow_bb_node ( _, _, this , _)
1048975 }
1049976
1050977 /** Whether this basic block contains the specified node */
1051978 predicate contains ( ControlFlowNode node ) {
1052- this . getAPart ( ) . contains ( node )
979+ py_flow_bb_node ( node , _ , this , _ )
1053980 }
1054981
1055982 /** Gets the nth node in this basic block */
1056983 ControlFlowNode getNode ( int n ) {
1057- exists ( BasicBlockPart part |
1058- part = this .getAPart ( ) and
1059- n = part .startIndex ( ) + part .indexOf ( result )
1060- )
984+ py_flow_bb_node ( result , _, this , n )
1061985 }
1062986
1063987 string toString ( ) {
@@ -1077,7 +1001,7 @@ class BasicBlock extends @py_flow_node {
10771001 }
10781002
10791003 cached BasicBlock getImmediateDominator ( ) {
1080- this .getAPart ( ) .getImmediateDominator ( ) = result . getAPart ( )
1004+ this .firstNode ( ) .getImmediateDominator ( ) . getBasicBlock ( ) = result
10811005 }
10821006
10831007 /** Dominance frontier of a node x is the set of all nodes `other` such that `this` dominates a predecessor
@@ -1093,10 +1017,9 @@ class BasicBlock extends @py_flow_node {
10931017
10941018 /** Gets the last node in this basic block */
10951019 ControlFlowNode getLastNode ( ) {
1096- exists ( BasicBlockPart part |
1097- part = this .getAPart ( ) and
1098- part .isLast ( ) and
1099- result = part .lastNode ( )
1020+ exists ( int i |
1021+ this .getNode ( i ) = result and
1022+ i = max ( int j | py_flow_bb_node ( _, _, this , j ) )
11001023 )
11011024 }
11021025
0 commit comments