Skip to content

Commit 1215da2

Browse files
authored
Merge pull request #1827 from jbj/sbb-tidy
C++: Tidy up SubBasicBlocks.qll
2 parents f980d20 + 8c610e4 commit 1215da2

File tree

4 files changed

+104
-76
lines changed

4 files changed

+104
-76
lines changed

config/identical-files.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
3737
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll"
3838
],
39+
"C++ SubBasicBlocks": [
40+
"cpp/ql/src/semmle/code/cpp/controlflow/SubBasicBlocks.qll",
41+
"cpp/ql/src/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll"
42+
],
3943
"IR Instruction": [
4044
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll",
4145
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll",

cpp/ql/src/semmle/code/cpp/controlflow/SubBasicBlocks.qll

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
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/dataflow/internal/SubBasicBlocks.qll
4-
//
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.
59

610
/**
711
* Provides the `SubBasicBlock` class, used for partitioning basic blocks in
@@ -53,7 +57,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
5357
* predecessors.
5458
*/
5559
predicate firstInBB() {
56-
exists(BasicBlock bb | this.getPosInBasicBlock(bb) = 0)
60+
exists(BasicBlock bb | this.getRankInBasicBlock(bb) = 1)
5761
}
5862

5963
/**
@@ -62,48 +66,73 @@ class SubBasicBlock extends ControlFlowNodeBase {
6266
*/
6367
predicate lastInBB() {
6468
exists(BasicBlock bb |
65-
this.getPosInBasicBlock(bb) = countSubBasicBlocksInBasicBlock(bb) - 1
69+
this.getRankInBasicBlock(bb) = countSubBasicBlocksInBasicBlock(bb)
6670
)
6771
}
6872

6973
/**
70-
* Gets the position of this `SubBasicBlock` in its containing basic block
71-
* `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()`.
7276
*/
73-
int getPosInBasicBlock(BasicBlock bb) {
74-
exists(int nodePos, int rnk |
75-
bb = this.(ControlFlowNode).getBasicBlock() and
76-
this = bb.getNode(nodePos) and
77-
nodePos = rank[rnk](int i | exists(SubBasicBlock n | n = bb.getNode(i))) and
78-
result = rnk - 1
77+
int getRankInBasicBlock(BasicBlock bb) {
78+
exists(int thisIndexInBB |
79+
thisIndexInBB = this.getIndexInBasicBlock(bb) and
80+
thisIndexInBB = rank[result](int i | i = any(SubBasicBlock n).getIndexInBasicBlock(bb))
7981
)
8082
}
8183

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+
93+
pragma[noinline]
94+
private int getIndexInBasicBlock(BasicBlock bb) {
95+
this = bb.getNode(result)
96+
}
97+
8298
/** Gets a successor in the control-flow graph of `SubBasicBlock`s. */
8399
SubBasicBlock getASuccessor() {
84100
this.lastInBB() and
85101
result = this.getBasicBlock().getASuccessor()
86102
or
87103
exists(BasicBlock bb |
88-
result.getPosInBasicBlock(bb) = this.getPosInBasicBlock(bb) + 1
104+
result.getRankInBasicBlock(bb) = this.getRankInBasicBlock(bb) + 1
89105
)
90106
}
91107

92108
/**
93-
* Gets the `pos`th control-flow node in this `SubBasicBlock`. Positions
94-
* 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
95111
* to `this`.
96112
*/
97-
ControlFlowNode getNode(int pos) {
98-
exists(BasicBlock bb | bb = this.getBasicBlock() |
99-
exists(int thisPos | this = bb.getNode(thisPos) |
100-
result = bb.getNode(thisPos + pos) and
101-
pos >= 0 and
102-
pos < this.getNumberOfNodes()
113+
ControlFlowNode getNode(int index) {
114+
exists(BasicBlock bb |
115+
exists(int outerIndex |
116+
result = bb.getNode(outerIndex) and
117+
index = outerToInnerIndex(bb, outerIndex)
103118
)
104119
)
105120
}
106121

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.
130+
pragma[nomagic]
131+
private int outerToInnerIndex(BasicBlock bb, int indexInBB) {
132+
indexInBB = result + this.getIndexInBasicBlock(bb) and
133+
result = [ 0 .. this.getNumberOfNodes() - 1 ]
134+
}
135+
107136
/** Gets a control-flow node in this `SubBasicBlock`. */
108137
ControlFlowNode getANode() {
109138
result = this.getNode(_)
@@ -144,17 +173,10 @@ class SubBasicBlock extends ControlFlowNodeBase {
144173
* always at least one.
145174
*/
146175
int getNumberOfNodes() {
147-
exists(BasicBlock bb | bb = this.getBasicBlock() |
148-
exists(int thisPos | this = bb.getNode(thisPos) |
149-
this.lastInBB() and
150-
result = bb.length() - thisPos
151-
or
152-
exists(SubBasicBlock succ, int succPos |
153-
succ.getPosInBasicBlock(bb) = this.getPosInBasicBlock(bb) + 1 and
154-
bb.getNode(succPos) = succ and
155-
result = succPos - thisPos
156-
)
157-
)
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)
158180
)
159181
}
160182

cpp/ql/src/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
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

cpp/ql/test/library-tests/sub_basic_blocks/sbb_test.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ string subBasicBlockDebugInfo(SubBasicBlock sbb) {
66
" [line " + sbb.getStart().getLocation().getStartLine() + "-" +
77
sbb.getEnd().getLocation().getEndLine() + ", " +
88
sbb.getNumberOfNodes() + " nodes, " +
9-
"pos " + sbb.getPosInBasicBlock(_) +
9+
"pos " + (sbb.getRankInBasicBlock(_) - 1) +
1010
any(string s | if sbb.firstInBB() then s = " (first in BB)" else s = "") +
1111
any(string s | if sbb.lastInBB() then s = " (last in BB)" else s = "") +
1212
", " +

0 commit comments

Comments
 (0)