1+ // NOTE: There are two copies of this file, and they must be kept identical:
2+ // - semmle/code/cpp/controlflow/SubBasicBlocks.qll
3+ // - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll
14//
2- // NOTE: Maintain this file in synchrony with
3- // semmlecode-cpp-queries/semmle/code/cpp/controlflow/SubBasicBlocks.qll
4- //
5- // This is a private copy of the `SubBasicBlocks` library for internal use by
6- // the data flow library. Having an extra copy can prevent non-monotonic
7- // recursion errors in queries that use both the data flow library and the
8- // `SubBasicBlocks` library.
5+ // The second one is a private copy of the `SubBasicBlocks` library for
6+ // internal use by the data flow library. Having an extra copy prevents
7+ // non-monotonic recursion errors in queries that use both the data flow
8+ // library and the `SubBasicBlocks` library.
99
1010/**
1111 * Provides the `SubBasicBlock` class, used for partitioning basic blocks in
@@ -57,7 +57,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
5757 * predecessors.
5858 */
5959 predicate firstInBB ( ) {
60- exists ( BasicBlock bb | this .getPosInBasicBlock ( bb ) = 0 )
60+ exists ( BasicBlock bb | this .getRankInBasicBlock ( bb ) = 1 )
6161 }
6262
6363 /**
@@ -66,22 +66,30 @@ class SubBasicBlock extends ControlFlowNodeBase {
6666 */
6767 predicate lastInBB ( ) {
6868 exists ( BasicBlock bb |
69- this .getPosInBasicBlock ( bb ) = countSubBasicBlocksInBasicBlock ( bb ) - 1
69+ this .getRankInBasicBlock ( bb ) = countSubBasicBlocksInBasicBlock ( bb )
7070 )
7171 }
7272
7373 /**
74- * Gets the position of this `SubBasicBlock` in its containing basic block
75- * `bb`, where `bb` is equal to `getBasicBlock()`.
74+ * Gets the (1-based) rank of this `SubBasicBlock` among the other `SubBasicBlock`s in
75+ * its containing basic block `bb`, where `bb` is equal to `getBasicBlock()`.
7676 */
77- int getPosInBasicBlock ( BasicBlock bb ) {
78- exists ( int thisIndexInBB , int rnk |
77+ int getRankInBasicBlock ( BasicBlock bb ) {
78+ exists ( int thisIndexInBB |
7979 thisIndexInBB = this .getIndexInBasicBlock ( bb ) and
80- thisIndexInBB = rank [ rnk ] ( int i | i = any ( SubBasicBlock n ) .getIndexInBasicBlock ( bb ) ) and
81- result = rnk - 1
80+ thisIndexInBB = rank [ result ] ( int i | i = any ( SubBasicBlock n ) .getIndexInBasicBlock ( bb ) )
8281 )
8382 }
8483
84+ /**
85+ * DEPRECATED: use `getRankInBasicBlock` instead. Note that this predicate
86+ * returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
87+ * position.
88+ */
89+ deprecated int getPosInBasicBlock ( BasicBlock bb ) {
90+ result = getRankInBasicBlock ( bb ) - 1
91+ }
92+
8593 pragma [ noinline]
8694 private int getIndexInBasicBlock ( BasicBlock bb ) {
8795 this = bb .getNode ( result )
@@ -93,28 +101,35 @@ class SubBasicBlock extends ControlFlowNodeBase {
93101 result = this .getBasicBlock ( ) .getASuccessor ( )
94102 or
95103 exists ( BasicBlock bb |
96- result .getPosInBasicBlock ( bb ) = this .getPosInBasicBlock ( bb ) + 1
104+ result .getRankInBasicBlock ( bb ) = this .getRankInBasicBlock ( bb ) + 1
97105 )
98106 }
99107
100108 /**
101- * Gets the `pos `th control-flow node in this `SubBasicBlock`. Positions
102- * start from 0, and the node at position 0 always exists and compares equal
109+ * Gets the `index `th control-flow node in this `SubBasicBlock`. Indexes
110+ * start from 0, and the node at index 0 always exists and compares equal
103111 * to `this`.
104112 */
105- pragma [ nomagic]
106- ControlFlowNode getNode ( int pos ) {
113+ ControlFlowNode getNode ( int index ) {
107114 exists ( BasicBlock bb |
108- exists ( int outerPos |
109- result = bb .getNode ( outerPos ) and
110- pos = outerPosToInnerPos ( bb , outerPos )
115+ exists ( int outerIndex |
116+ result = bb .getNode ( outerIndex ) and
117+ index = outerToInnerIndex ( bb , outerIndex )
111118 )
112119 )
113120 }
114121
122+ /**
123+ * Gets the index of the node in this `SubBasicBlock` that has `indexInBB` in
124+ * `bb`, where `bb` is equal to `getBasicBlock()`.
125+ */
126+ // This predicate is factored out of `getNode` to ensure a good join order.
127+ // It's sensitive to bad magic, so it has `pragma[nomagic]` on it. For
128+ // example, it can get very slow if `getNode` is pragma[nomagic], which could
129+ // mean it might get very slow if `getNode` is used in the wrong context.
115130 pragma [ nomagic]
116- private int outerPosToInnerPos ( BasicBlock bb , int posInBB ) {
117- posInBB = result + this .getIndexInBasicBlock ( bb ) and
131+ private int outerToInnerIndex ( BasicBlock bb , int indexInBB ) {
132+ indexInBB = result + this .getIndexInBasicBlock ( bb ) and
118133 result = [ 0 .. this .getNumberOfNodes ( ) - 1 ]
119134 }
120135
@@ -157,24 +172,11 @@ class SubBasicBlock extends ControlFlowNodeBase {
157172 * Gets the number of control-flow nodes in this `SubBasicBlock`. There is
158173 * always at least one.
159174 */
160- pragma [ noopt]
161175 int getNumberOfNodes ( ) {
162- exists ( BasicBlock bb | bb = this .getBasicBlock ( ) |
163- exists ( int thisPos | this = bb .getNode ( thisPos ) |
164- exists ( int bbLength |
165- this .lastInBB ( ) and
166- bbLength = bb .length ( ) and
167- result = bbLength - thisPos
168- )
169- or
170- exists ( SubBasicBlock succ , int succPos , int thisRank , int succRank |
171- thisRank = this .getPosInBasicBlock ( bb ) and
172- succRank = thisRank + 1 and
173- succRank = succ .getPosInBasicBlock ( bb ) and
174- bb .getNode ( succPos ) = succ and
175- result = succPos - thisPos
176- )
177- )
176+ exists ( BasicBlock bb |
177+ if this .lastInBB ( )
178+ then result = bb .length ( ) - this .getIndexInBasicBlock ( bb )
179+ else result = this .getASuccessor ( ) .getIndexInBasicBlock ( bb ) - this .getIndexInBasicBlock ( bb )
178180 )
179181 }
180182
0 commit comments