Skip to content

Commit 119837b

Browse files
committed
BasicBlock: Add CFG signature.
1 parent 0d0eaa2 commit 119837b

File tree

1 file changed

+125
-2
lines changed

1 file changed

+125
-2
lines changed

shared/controlflow/codeql/controlflow/BasicBlock.qll

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ private import codeql.util.Location
1212

1313
/** Provides the language-specific input specification. */
1414
signature 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

Comments
 (0)