Skip to content

Commit 3bdfdd0

Browse files
committed
C++: Change all the 'ensures' and (and most 'compares') predicates to be inlined to prevent explosions. Also remove the caching since this is't necessary now that the main recursion is cached.
1 parent 404dd33 commit 3bdfdd0

File tree

1 file changed

+33
-27
lines changed

1 file changed

+33
-27
lines changed

cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -98,55 +98,55 @@ abstract private class GuardConditionImpl extends Expr {
9898
* being short-circuited) then it will only control blocks dominated by the
9999
* true (for `&&`) or false (for `||`) branch.
100100
*/
101-
cached
102101
final predicate controls(BasicBlock controlled, boolean testIsTrue) {
103102
this.valueControls(controlled, any(BooleanValue bv | bv.getValue() = testIsTrue))
104103
}
105104

106105
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
106+
pragma[inline]
107107
abstract predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue);
108108

109109
/**
110110
* Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`.
111111
* If `isLessThan = false` then this implies `left >= right + k`.
112112
*/
113-
cached
113+
pragma[inline]
114114
abstract predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan);
115115

116116
/**
117117
* Holds if (determined by this guard) `e < k` evaluates to `isLessThan` if
118118
* this expression evaluates to `value`.
119119
*/
120-
cached
120+
pragma[inline]
121121
abstract predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value);
122122

123123
/**
124124
* Holds if (determined by this guard) `e < k` must be `isLessThan` in `block`.
125125
* If `isLessThan = false` then this implies `e >= k`.
126126
*/
127-
cached
127+
pragma[inline]
128128
abstract predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan);
129129

130130
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
131-
cached
131+
pragma[inline]
132132
abstract predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue);
133133

134134
/**
135135
* Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`.
136136
* If `areEqual = false` then this implies `left != right + k`.
137137
*/
138-
cached
138+
pragma[inline]
139139
abstract predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual);
140140

141141
/** Holds if (determined by this guard) `e == k` evaluates to `areEqual` if this expression evaluates to `value`. */
142-
cached
142+
pragma[inline]
143143
abstract predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value);
144144

145145
/**
146146
* Holds if (determined by this guard) `e == k` must be `areEqual` in `block`.
147147
* If `areEqual = false` then this implies `e != k`.
148148
*/
149-
cached
149+
pragma[inline]
150150
abstract predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual);
151151
}
152152

@@ -187,12 +187,14 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
187187
)
188188
}
189189

190+
pragma[inline]
190191
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
191192
exists(boolean testIsTrue |
192193
this.comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
193194
)
194195
}
195196

197+
pragma[inline]
196198
override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) {
197199
exists(AbstractValue value |
198200
this.comparesLt(e, k, isLessThan, value) and this.valueControls(block, value)
@@ -207,6 +209,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
207209
)
208210
}
209211

212+
pragma[inline]
210213
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
211214
exists(boolean testIsTrue |
212215
this.comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
@@ -222,6 +225,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
222225
)
223226
}
224227

228+
pragma[inline]
225229
override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) {
226230
exists(AbstractValue value |
227231
this.comparesEq(e, k, areEqual, value) and this.valueControls(block, value)
@@ -244,6 +248,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
244248
this.controlsBlock(controlled, v)
245249
}
246250

251+
pragma[inline]
247252
override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) {
248253
exists(Instruction li, Instruction ri |
249254
li.getUnconvertedResultExpression() = left and
@@ -252,13 +257,15 @@ private class GuardConditionFromIR extends GuardConditionImpl {
252257
)
253258
}
254259

260+
pragma[inline]
255261
override predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value) {
256262
exists(Instruction i |
257263
i.getUnconvertedResultExpression() = e and
258264
ir.comparesLt(i.getAUse(), k, isLessThan, value)
259265
)
260266
}
261267

268+
pragma[inline]
262269
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
263270
exists(Instruction li, Instruction ri, boolean testIsTrue |
264271
li.getUnconvertedResultExpression() = left and
@@ -268,6 +275,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
268275
)
269276
}
270277

278+
pragma[inline]
271279
override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) {
272280
exists(Instruction i, AbstractValue value |
273281
i.getUnconvertedResultExpression() = e and
@@ -276,6 +284,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
276284
)
277285
}
278286

287+
pragma[inline]
279288
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
280289
exists(Instruction li, Instruction ri |
281290
li.getUnconvertedResultExpression() = left and
@@ -284,6 +293,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
284293
)
285294
}
286295

296+
pragma[inline]
287297
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
288298
exists(Instruction li, Instruction ri, boolean testIsTrue |
289299
li.getUnconvertedResultExpression() = left and
@@ -293,13 +303,15 @@ private class GuardConditionFromIR extends GuardConditionImpl {
293303
)
294304
}
295305

306+
pragma[inline]
296307
override predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value) {
297308
exists(Instruction i |
298309
i.getUnconvertedResultExpression() = e and
299310
ir.comparesEq(i.getAUse(), k, areEqual, value)
300311
)
301312
}
302313

314+
pragma[inline]
303315
override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) {
304316
exists(Instruction i, AbstractValue value |
305317
i.getUnconvertedResultExpression() = e and
@@ -362,7 +374,6 @@ private predicate nonExcludedIRAndBasicBlock(IRBlock irb, BasicBlock controlled)
362374
* For performance reasons conditions inside static local initializers or
363375
* global initializers are not considered `IRGuardCondition`s.
364376
*/
365-
cached
366377
class IRGuardCondition extends Instruction {
367378
Instruction branch;
368379

@@ -383,7 +394,7 @@ class IRGuardCondition extends Instruction {
383394
* gcc extension.
384395
*
385396
* The implementation of all four follows the same structure: Each relation
386-
* has a cached user-facing predicate that. For example,
397+
* has a user-facing predicate that. For example,
387398
* `GuardCondition::comparesEq` calls `compares_eq`. This predicate has
388399
* several cases that recursively decompose the relation to bring it to a
389400
* canonical form (i.e., a relation of the form `e1 == e2 + k`). The base
@@ -393,7 +404,6 @@ class IRGuardCondition extends Instruction {
393404
* `e1 + k1 == e2 + k2` into canonical the form `e1 == e2 + (k2 - k1)`.
394405
*/
395406

396-
cached
397407
IRGuardCondition() { branch = getBranchForCondition(this) }
398408

399409
/**
@@ -402,7 +412,6 @@ class IRGuardCondition extends Instruction {
402412
*
403413
* For details on what "controls" mean, see the QLDoc for `controls`.
404414
*/
405-
cached
406415
predicate valueControls(IRBlock controlled, AbstractValue v) {
407416
// This condition must determine the flow of control; that is, this
408417
// node must be a top-level condition.
@@ -440,7 +449,6 @@ class IRGuardCondition extends Instruction {
440449
* being short-circuited) then it will only control blocks dominated by the
441450
* true (for `&&`) or false (for `||`) branch.
442451
*/
443-
cached
444452
predicate controls(IRBlock controlled, boolean testIsTrue) {
445453
this.valueControls(controlled, any(BooleanValue bv | bv.getValue() = testIsTrue))
446454
}
@@ -449,7 +457,6 @@ class IRGuardCondition extends Instruction {
449457
* Holds if the control-flow edge `(pred, succ)` may be taken only if
450458
* the value of this condition is `v`.
451459
*/
452-
cached
453460
predicate valueControlsEdge(IRBlock pred, IRBlock succ, AbstractValue v) {
454461
pred.getASuccessor() = succ and
455462
this.valueControls(pred, v)
@@ -468,7 +475,6 @@ class IRGuardCondition extends Instruction {
468475
* Holds if the control-flow edge `(pred, succ)` may be taken only if
469476
* the value of this condition is `testIsTrue`.
470477
*/
471-
cached
472478
final predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) {
473479
this.valueControlsEdge(pred, succ, any(BooleanValue bv | bv.getValue() = testIsTrue))
474480
}
@@ -506,7 +512,7 @@ class IRGuardCondition extends Instruction {
506512
}
507513

508514
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
509-
cached
515+
pragma[inline]
510516
predicate comparesLt(Operand left, Operand right, int k, boolean isLessThan, boolean testIsTrue) {
511517
exists(BooleanValue value |
512518
compares_lt(valueNumber(this), left, right, k, isLessThan, value) and
@@ -518,7 +524,7 @@ class IRGuardCondition extends Instruction {
518524
* Holds if (determined by this guard) `op < k` evaluates to `isLessThan` if
519525
* this expression evaluates to `value`.
520526
*/
521-
cached
527+
pragma[inline]
522528
predicate comparesLt(Operand op, int k, boolean isLessThan, AbstractValue value) {
523529
compares_lt(valueNumber(this), op, k, isLessThan, value)
524530
}
@@ -527,7 +533,7 @@ class IRGuardCondition extends Instruction {
527533
* Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`.
528534
* If `isLessThan = false` then this implies `left >= right + k`.
529535
*/
530-
cached
536+
pragma[inline]
531537
predicate ensuresLt(Operand left, Operand right, int k, IRBlock block, boolean isLessThan) {
532538
exists(AbstractValue value |
533539
compares_lt(valueNumber(this), left, right, k, isLessThan, value) and
@@ -539,7 +545,7 @@ class IRGuardCondition extends Instruction {
539545
* Holds if (determined by this guard) `op < k` must be `isLessThan` in `block`.
540546
* If `isLessThan = false` then this implies `op >= k`.
541547
*/
542-
cached
548+
pragma[inline]
543549
predicate ensuresLt(Operand op, int k, IRBlock block, boolean isLessThan) {
544550
exists(AbstractValue value |
545551
compares_lt(valueNumber(this), op, k, isLessThan, value) and
@@ -551,7 +557,7 @@ class IRGuardCondition extends Instruction {
551557
* Holds if (determined by this guard) `left < right + k` must be `isLessThan` on the edge from
552558
* `pred` to `succ`. If `isLessThan = false` then this implies `left >= right + k`.
553559
*/
554-
cached
560+
pragma[inline]
555561
predicate ensuresLtEdge(
556562
Operand left, Operand right, int k, IRBlock pred, IRBlock succ, boolean isLessThan
557563
) {
@@ -565,7 +571,7 @@ class IRGuardCondition extends Instruction {
565571
* Holds if (determined by this guard) `op < k` must be `isLessThan` on the edge from
566572
* `pred` to `succ`. If `isLessThan = false` then this implies `op >= k`.
567573
*/
568-
cached
574+
pragma[inline]
569575
predicate ensuresLtEdge(Operand left, int k, IRBlock pred, IRBlock succ, boolean isLessThan) {
570576
exists(AbstractValue value |
571577
compares_lt(valueNumber(this), left, k, isLessThan, value) and
@@ -574,7 +580,7 @@ class IRGuardCondition extends Instruction {
574580
}
575581

576582
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
577-
cached
583+
pragma[inline]
578584
predicate comparesEq(Operand left, Operand right, int k, boolean areEqual, boolean testIsTrue) {
579585
exists(BooleanValue value |
580586
compares_eq(valueNumber(this), left, right, k, areEqual, value) and
@@ -583,7 +589,7 @@ class IRGuardCondition extends Instruction {
583589
}
584590

585591
/** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */
586-
cached
592+
pragma[inline]
587593
predicate comparesEq(Operand op, int k, boolean areEqual, AbstractValue value) {
588594
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value)
589595
}
@@ -592,7 +598,7 @@ class IRGuardCondition extends Instruction {
592598
* Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`.
593599
* If `areEqual = false` then this implies `left != right + k`.
594600
*/
595-
cached
601+
pragma[inline]
596602
predicate ensuresEq(Operand left, Operand right, int k, IRBlock block, boolean areEqual) {
597603
exists(AbstractValue value |
598604
compares_eq(valueNumber(this), left, right, k, areEqual, value) and
@@ -604,7 +610,7 @@ class IRGuardCondition extends Instruction {
604610
* Holds if (determined by this guard) `op == k` must be `areEqual` in `block`.
605611
* If `areEqual = false` then this implies `op != k`.
606612
*/
607-
cached
613+
pragma[inline]
608614
predicate ensuresEq(Operand op, int k, IRBlock block, boolean areEqual) {
609615
exists(AbstractValue value |
610616
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value) and
@@ -616,7 +622,7 @@ class IRGuardCondition extends Instruction {
616622
* Holds if (determined by this guard) `left == right + k` must be `areEqual` on the edge from
617623
* `pred` to `succ`. If `areEqual = false` then this implies `left != right + k`.
618624
*/
619-
cached
625+
pragma[inline]
620626
predicate ensuresEqEdge(
621627
Operand left, Operand right, int k, IRBlock pred, IRBlock succ, boolean areEqual
622628
) {
@@ -630,7 +636,7 @@ class IRGuardCondition extends Instruction {
630636
* Holds if (determined by this guard) `op == k` must be `areEqual` on the edge from
631637
* `pred` to `succ`. If `areEqual = false` then this implies `op != k`.
632638
*/
633-
cached
639+
pragma[inline]
634640
predicate ensuresEqEdge(Operand op, int k, IRBlock pred, IRBlock succ, boolean areEqual) {
635641
exists(AbstractValue value |
636642
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value) and

0 commit comments

Comments
 (0)