44
55import java
66import Dominance
7+ private import codeql.controlflow.BasicBlock as BB
78
8- cached
9- private module BasicBlockStage {
10- cached
11- predicate ref ( ) { any ( ) }
9+ private module Input implements BB:: InputSig< Location > {
10+ import SuccessorType
1211
13- cached
14- predicate backref ( ) {
15- ( exists ( any ( BasicBlock bb ) .getABBSuccessor ( ) ) implies any ( ) ) and
16- ( exists ( any ( BasicBlock bb ) .getNode ( _) ) implies any ( ) ) and
17- ( exists ( any ( BasicBlock bb ) .length ( ) ) implies any ( ) )
12+ /** Hold if `t` represents a conditional successor type. */
13+ predicate successorTypeIsCondition ( SuccessorType t ) { none ( ) }
14+
15+ /** A delineated part of the AST with its own CFG. */
16+ class CfgScope = Callable ;
17+
18+ /** The class of control flow nodes. */
19+ class Node = ControlFlowNode ;
20+
21+ /** Gets the CFG scope in which this node occurs. */
22+ CfgScope nodeGetCfgScope ( Node node ) { node .getEnclosingCallable ( ) = result }
23+
24+ private Node getASpecificSuccessor ( Node node , SuccessorType t ) {
25+ node .( ConditionNode ) .getABranchSuccessor ( t .( BooleanSuccessor ) .getValue ( ) ) = result
26+ or
27+ node .getAnExceptionSuccessor ( ) = result and t instanceof ExceptionSuccessor
28+ }
29+
30+ /** Gets an immediate successor of this node. */
31+ Node nodeGetASuccessor ( Node node , SuccessorType t ) {
32+ result = getASpecificSuccessor ( node , t )
33+ or
34+ node .getASuccessor ( ) = result and
35+ t instanceof NormalSuccessor and
36+ not result = getASpecificSuccessor ( node , _)
1837 }
38+
39+ /**
40+ * Holds if `node` represents an entry node to be used when calculating
41+ * dominance.
42+ */
43+ predicate nodeIsDominanceEntry ( Node node ) {
44+ exists ( Stmt entrystmt | entrystmt = node .asStmt ( ) |
45+ exists ( Callable c | entrystmt = c .getBody ( ) )
46+ or
47+ // This disjunct is technically superfluous, but safeguards against extractor problems.
48+ entrystmt instanceof BlockStmt and
49+ not exists ( entrystmt .getEnclosingCallable ( ) ) and
50+ not entrystmt .getParent ( ) instanceof Stmt
51+ )
52+ }
53+
54+ /**
55+ * Holds if `node` represents an exit node to be used when calculating
56+ * post dominance.
57+ */
58+ predicate nodeIsPostDominanceExit ( Node node ) { node instanceof ControlFlow:: ExitNode }
59+ }
60+
61+ private module BbImpl = BB:: Make< Location , Input > ;
62+
63+ import BbImpl
64+
65+ /** Holds if the dominance relation is calculated for `bb`. */
66+ predicate hasDominanceInformation ( BasicBlock bb ) {
67+ exists ( BasicBlock entry |
68+ Input:: nodeIsDominanceEntry ( entry .getFirstNode ( ) ) and entry .getASuccessor * ( ) = bb
69+ )
1970}
2071
2172/**
@@ -24,71 +75,27 @@ private module BasicBlockStage {
2475 * A basic block is a series of nodes with no control-flow branching, which can
2576 * often be treated as a unit in analyses.
2677 */
27- class BasicBlock extends ControlFlowNode {
28- cached
29- BasicBlock ( ) {
30- BasicBlockStage:: ref ( ) and
31- not exists ( this .getAPredecessor ( ) ) and
32- exists ( this .getASuccessor ( ) )
33- or
34- strictcount ( this .getAPredecessor ( ) ) > 1
35- or
36- exists ( ControlFlowNode pred | pred = this .getAPredecessor ( ) |
37- strictcount ( pred .getASuccessor ( ) ) > 1
38- )
39- }
78+ class BasicBlock extends BbImpl:: BasicBlock {
79+ /** Gets the immediately enclosing callable whose body contains this node. */
80+ Callable getEnclosingCallable ( ) { result = this .getScope ( ) }
4081
4182 /** Gets an immediate successor of this basic block. */
42- cached
43- BasicBlock getABBSuccessor ( ) {
44- BasicBlockStage:: ref ( ) and
45- result = this .getLastNode ( ) .getASuccessor ( )
46- }
83+ BasicBlock getABBSuccessor ( ) { result = this .getASuccessor ( ) }
4784
4885 /** Gets an immediate predecessor of this basic block. */
4986 BasicBlock getABBPredecessor ( ) { result .getABBSuccessor ( ) = this }
5087
51- /** Gets a control-flow node contained in this basic block. */
52- ControlFlowNode getANode ( ) { result = this .getNode ( _) }
53-
54- /** Gets the control-flow node at a specific (zero-indexed) position in this basic block. */
55- cached
56- ControlFlowNode getNode ( int pos ) {
57- BasicBlockStage:: ref ( ) and
58- result = this and
59- pos = 0
60- or
61- exists ( ControlFlowNode mid , int mid_pos | pos = mid_pos + 1 |
62- this .getNode ( mid_pos ) = mid and
63- mid .getASuccessor ( ) = result and
64- not result instanceof BasicBlock
65- )
66- }
67-
68- /** Gets the first control-flow node in this basic block. */
69- ControlFlowNode getFirstNode ( ) { result = this }
70-
71- /** Gets the last control-flow node in this basic block. */
72- ControlFlowNode getLastNode ( ) { result = this .getNode ( this .length ( ) - 1 ) }
73-
74- /** Gets the number of control-flow nodes contained in this basic block. */
75- cached
76- int length ( ) {
77- BasicBlockStage:: ref ( ) and
78- result = strictcount ( this .getANode ( ) )
79- }
80-
8188 /** Holds if this basic block strictly dominates `node`. */
82- predicate bbStrictlyDominates ( BasicBlock node ) { bbStrictlyDominates ( this , node ) }
89+ predicate bbStrictlyDominates ( BasicBlock node ) { this . strictlyDominates ( node ) }
8390
8491 /** Holds if this basic block dominates `node`. (This is reflexive.) */
85- predicate bbDominates ( BasicBlock node ) { bbDominates ( this , node ) }
92+ predicate bbDominates ( BasicBlock node ) { this . dominates ( node ) }
8693
8794 /** Holds if this basic block strictly post-dominates `node`. */
88- predicate bbStrictlyPostDominates ( BasicBlock node ) { bbStrictlyPostDominates ( this , node ) }
95+ predicate bbStrictlyPostDominates ( BasicBlock node ) { this . strictlyPostDominates ( node ) }
8996
9097 /** Holds if this basic block post-dominates `node`. (This is reflexive.) */
91- predicate bbPostDominates ( BasicBlock node ) { bbPostDominates ( this , node ) }
98+ predicate bbPostDominates ( BasicBlock node ) { this . postDominates ( node ) }
9299}
93100
94101/** A basic block that ends in an exit node. */
0 commit comments