@@ -12,7 +12,11 @@ private import codeql.util.Location
1212
1313/ * * Provides the language- specific input specification. * /
1414signature module InputSig< LocationSig Location> {
15- class SuccessorType ;
15+ /** The type of a control flow successor. */
16+ class SuccessorType {
17+ /** Gets a textual representation of this successor type. */
18+ string toString ( ) ;
19+ }
1620
1721 /** Hold if `t` represents a conditional successor type. */
1822 predicate successorTypeIsCondition ( SuccessorType t ) ;
@@ -47,12 +51,131 @@ signature module InputSig<LocationSig Location> {
4751 predicate nodeIsPostDominanceExit ( Node node ) ;
4852}
4953
54+ signature module CfgSig< LocationSig Location> {
55+ /** A control flow node. */
56+ class ControlFlowNode {
57+ /** Gets a textual representation of this control flow node. */
58+ string toString ( ) ;
59+
60+ /** Gets the location of this control flow node. */
61+ Location getLocation ( ) ;
62+ }
63+
64+ /** The type of a control flow successor. */
65+ class SuccessorType {
66+ /** Gets a textual representation of this successor type. */
67+ string toString ( ) ;
68+ }
69+
70+ /**
71+ * A basic block, that is, a maximal straight-line sequence of control flow nodes
72+ * without branches or joins.
73+ */
74+ class BasicBlock {
75+ /** Gets a textual representation of this basic block. */
76+ string toString ( ) ;
77+
78+ /** Gets the location of this basic block. */
79+ Location getLocation ( ) ;
80+
81+ /** Gets the control flow node at a specific (zero-indexed) position in this basic block. */
82+ ControlFlowNode getNode ( int pos ) ;
83+
84+ /** Gets the last control flow node in this basic block. */
85+ ControlFlowNode getLastNode ( ) ;
86+
87+ /** Gets the length of this basic block. */
88+ int length ( ) ;
89+
90+ /** Gets an immediate successor of this basic block, if any. */
91+ BasicBlock getASuccessor ( ) ;
92+
93+ /** Gets an immediate successor of this basic block of a given type, if any. */
94+ BasicBlock getASuccessor ( SuccessorType t ) ;
95+
96+ /**
97+ * Holds if this basic block strictly dominates basic block `bb`.
98+ *
99+ * That is, all paths reaching `bb` from the entry point basic block must
100+ * go through this basic block and this basic block is different from `bb`.
101+ */
102+ predicate strictlyDominates ( BasicBlock bb ) ;
103+
104+ /**
105+ * Holds if this basic block dominates basic block `bb`.
106+ *
107+ * That is, all paths reaching `bb` from the entry point basic block must
108+ * go through this basic block.
109+ */
110+ predicate dominates ( BasicBlock bb ) ;
111+
112+ /**
113+ * Holds if `df` is in the dominance frontier of this basic block. That is,
114+ * this basic block dominates a predecessor of `df`, but does not dominate
115+ * `df` itself. I.e., it is equivaluent to:
116+ * ```
117+ * this.dominates(df.getAPredecessor()) and not this.strictlyDominates(df)
118+ * ```
119+ */
120+ predicate inDominanceFrontier ( BasicBlock df ) ;
121+
122+ /**
123+ * Gets the basic block that immediately dominates this basic block, if any.
124+ *
125+ * That is, the result is the unique basic block satisfying:
126+ * 1. The result strictly dominates this basic block.
127+ * 2. There exists no other basic block that is strictly dominated by the
128+ * result and which strictly dominates this basic block.
129+ *
130+ * All basic blocks, except entry basic blocks, have a unique immediate
131+ * dominator.
132+ */
133+ BasicBlock getImmediateDominator ( ) ;
134+
135+ /**
136+ * Holds if this basic block strictly post-dominates basic block `bb`.
137+ *
138+ * That is, all paths reaching a normal exit point basic block from basic
139+ * block `bb` must go through this basic block and this basic block is
140+ * different from `bb`.
141+ */
142+ predicate strictlyPostDominates ( BasicBlock bb ) ;
143+
144+ /**
145+ * Holds if this basic block post-dominates basic block `bb`.
146+ *
147+ * That is, all paths reaching a normal exit point basic block from basic
148+ * block `bb` must go through this basic block.
149+ */
150+ predicate postDominates ( BasicBlock bb ) ;
151+ }
152+
153+ /**
154+ * Holds if `bb1` has `bb2` as a direct successor and the edge between `bb1`
155+ * and `bb2` is a dominating edge.
156+ *
157+ * An edge `(bb1, bb2)` is dominating if there exists a basic block that can
158+ * only be reached from the entry block by going through `(bb1, bb2)`. This
159+ * implies that `(bb1, bb2)` dominates its endpoint `bb2`. I.e., `bb2` can
160+ * only be reached from the entry block by going via `(bb1, bb2)`.
161+ *
162+ * This is a necessary and sufficient condition for an edge to dominate some
163+ * block, and therefore `dominatingEdge(bb1, bb2) and bb2.dominates(bb3)`
164+ * means that the edge `(bb1, bb2)` dominates `bb3`.
165+ */
166+ predicate dominatingEdge ( BasicBlock bb1 , BasicBlock bb2 ) ;
167+ }
168+
50169/**
51170 * Provides a basic block construction on top of a control flow graph.
52171 */
53- module Make< LocationSig Location, InputSig< Location > Input> {
172+ module Make< LocationSig Location, InputSig< Location > Input> implements CfgSig < Location > {
54173 private import Input
55174
175+ class ControlFlowNode = Input:: Node ;
176+
177+ class SuccessorType = Input:: SuccessorType ;
178+
56179 /**
57180 * A basic block, that is, a maximal straight-line sequence of control flow nodes
58181 * without branches or joins.
0 commit comments