Skip to content

Commit 9cf1443

Browse files
committed
C++: Change all the 'ensures' predicates to be inlined to prevent explosions. Also remove the caching on 'compares' since this is't necessary now that the main recursion is cached.
1 parent 744a6b2 commit 9cf1443

File tree

1 file changed

+21
-27
lines changed

1 file changed

+21
-27
lines changed

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

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ 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
}
@@ -110,43 +109,40 @@ abstract private class GuardConditionImpl extends Expr {
110109
* Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`.
111110
* If `isLessThan = false` then this implies `left >= right + k`.
112111
*/
113-
cached
112+
pragma[inline]
114113
abstract predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan);
115114

116115
/**
117116
* Holds if (determined by this guard) `e < k` evaluates to `isLessThan` if
118117
* this expression evaluates to `value`.
119118
*/
120-
cached
121119
abstract predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value);
122120

123121
/**
124122
* Holds if (determined by this guard) `e < k` must be `isLessThan` in `block`.
125123
* If `isLessThan = false` then this implies `e >= k`.
126124
*/
127-
cached
125+
pragma[inline]
128126
abstract predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan);
129127

130128
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
131-
cached
132129
abstract predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue);
133130

134131
/**
135132
* Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`.
136133
* If `areEqual = false` then this implies `left != right + k`.
137134
*/
138-
cached
135+
pragma[inline]
139136
abstract predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual);
140137

141138
/** Holds if (determined by this guard) `e == k` evaluates to `areEqual` if this expression evaluates to `value`. */
142-
cached
143139
abstract predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value);
144140

145141
/**
146142
* Holds if (determined by this guard) `e == k` must be `areEqual` in `block`.
147143
* If `areEqual = false` then this implies `e != k`.
148144
*/
149-
cached
145+
pragma[inline]
150146
abstract predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual);
151147
}
152148

@@ -187,12 +183,14 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
187183
)
188184
}
189185

186+
pragma[inline]
190187
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
191188
exists(boolean testIsTrue |
192189
this.comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
193190
)
194191
}
195192

193+
pragma[inline]
196194
override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) {
197195
exists(AbstractValue value |
198196
this.comparesLt(e, k, isLessThan, value) and this.valueControls(block, value)
@@ -207,6 +205,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
207205
)
208206
}
209207

208+
pragma[inline]
210209
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
211210
exists(boolean testIsTrue |
212211
this.comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
@@ -222,6 +221,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
222221
)
223222
}
224223

224+
pragma[inline]
225225
override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) {
226226
exists(AbstractValue value |
227227
this.comparesEq(e, k, areEqual, value) and this.valueControls(block, value)
@@ -259,6 +259,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
259259
)
260260
}
261261

262+
pragma[inline]
262263
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
263264
exists(Instruction li, Instruction ri, boolean testIsTrue |
264265
li.getUnconvertedResultExpression() = left and
@@ -268,6 +269,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
268269
)
269270
}
270271

272+
pragma[inline]
271273
override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) {
272274
exists(Instruction i, AbstractValue value |
273275
i.getUnconvertedResultExpression() = e and
@@ -284,6 +286,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
284286
)
285287
}
286288

289+
pragma[inline]
287290
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
288291
exists(Instruction li, Instruction ri, boolean testIsTrue |
289292
li.getUnconvertedResultExpression() = left and
@@ -300,6 +303,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
300303
)
301304
}
302305

306+
pragma[inline]
303307
override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) {
304308
exists(Instruction i, AbstractValue value |
305309
i.getUnconvertedResultExpression() = e and
@@ -362,7 +366,6 @@ private predicate nonExcludedIRAndBasicBlock(IRBlock irb, BasicBlock controlled)
362366
* For performance reasons conditions inside static local initializers or
363367
* global initializers are not considered `IRGuardCondition`s.
364368
*/
365-
cached
366369
class IRGuardCondition extends Instruction {
367370
Instruction branch;
368371

@@ -383,7 +386,7 @@ class IRGuardCondition extends Instruction {
383386
* gcc extension.
384387
*
385388
* The implementation of all four follows the same structure: Each relation
386-
* has a cached user-facing predicate that. For example,
389+
* has a user-facing predicate that. For example,
387390
* `GuardCondition::comparesEq` calls `compares_eq`. This predicate has
388391
* several cases that recursively decompose the relation to bring it to a
389392
* canonical form (i.e., a relation of the form `e1 == e2 + k`). The base
@@ -393,7 +396,6 @@ class IRGuardCondition extends Instruction {
393396
* `e1 + k1 == e2 + k2` into canonical the form `e1 == e2 + (k2 - k1)`.
394397
*/
395398

396-
cached
397399
IRGuardCondition() { branch = getBranchForCondition(this) }
398400

399401
/**
@@ -402,7 +404,6 @@ class IRGuardCondition extends Instruction {
402404
*
403405
* For details on what "controls" mean, see the QLDoc for `controls`.
404406
*/
405-
cached
406407
predicate valueControls(IRBlock controlled, AbstractValue v) {
407408
// This condition must determine the flow of control; that is, this
408409
// node must be a top-level condition.
@@ -440,7 +441,6 @@ class IRGuardCondition extends Instruction {
440441
* being short-circuited) then it will only control blocks dominated by the
441442
* true (for `&&`) or false (for `||`) branch.
442443
*/
443-
cached
444444
predicate controls(IRBlock controlled, boolean testIsTrue) {
445445
this.valueControls(controlled, any(BooleanValue bv | bv.getValue() = testIsTrue))
446446
}
@@ -449,7 +449,6 @@ class IRGuardCondition extends Instruction {
449449
* Holds if the control-flow edge `(pred, succ)` may be taken only if
450450
* the value of this condition is `v`.
451451
*/
452-
cached
453452
predicate valueControlsEdge(IRBlock pred, IRBlock succ, AbstractValue v) {
454453
pred.getASuccessor() = succ and
455454
this.valueControls(pred, v)
@@ -468,7 +467,6 @@ class IRGuardCondition extends Instruction {
468467
* Holds if the control-flow edge `(pred, succ)` may be taken only if
469468
* the value of this condition is `testIsTrue`.
470469
*/
471-
cached
472470
final predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) {
473471
this.valueControlsEdge(pred, succ, any(BooleanValue bv | bv.getValue() = testIsTrue))
474472
}
@@ -506,7 +504,6 @@ class IRGuardCondition extends Instruction {
506504
}
507505

508506
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
509-
cached
510507
predicate comparesLt(Operand left, Operand right, int k, boolean isLessThan, boolean testIsTrue) {
511508
exists(BooleanValue value |
512509
compares_lt(valueNumber(this), left, right, k, isLessThan, value) and
@@ -518,7 +515,6 @@ class IRGuardCondition extends Instruction {
518515
* Holds if (determined by this guard) `op < k` evaluates to `isLessThan` if
519516
* this expression evaluates to `value`.
520517
*/
521-
cached
522518
predicate comparesLt(Operand op, int k, boolean isLessThan, AbstractValue value) {
523519
compares_lt(valueNumber(this), op, k, isLessThan, value)
524520
}
@@ -527,7 +523,7 @@ class IRGuardCondition extends Instruction {
527523
* Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`.
528524
* If `isLessThan = false` then this implies `left >= right + k`.
529525
*/
530-
cached
526+
pragma[inline]
531527
predicate ensuresLt(Operand left, Operand right, int k, IRBlock block, boolean isLessThan) {
532528
exists(AbstractValue value |
533529
compares_lt(valueNumber(this), left, right, k, isLessThan, value) and
@@ -539,7 +535,7 @@ class IRGuardCondition extends Instruction {
539535
* Holds if (determined by this guard) `op < k` must be `isLessThan` in `block`.
540536
* If `isLessThan = false` then this implies `op >= k`.
541537
*/
542-
cached
538+
pragma[inline]
543539
predicate ensuresLt(Operand op, int k, IRBlock block, boolean isLessThan) {
544540
exists(AbstractValue value |
545541
compares_lt(valueNumber(this), op, k, isLessThan, value) and
@@ -551,7 +547,7 @@ class IRGuardCondition extends Instruction {
551547
* Holds if (determined by this guard) `left < right + k` must be `isLessThan` on the edge from
552548
* `pred` to `succ`. If `isLessThan = false` then this implies `left >= right + k`.
553549
*/
554-
cached
550+
pragma[inline]
555551
predicate ensuresLtEdge(
556552
Operand left, Operand right, int k, IRBlock pred, IRBlock succ, boolean isLessThan
557553
) {
@@ -565,7 +561,7 @@ class IRGuardCondition extends Instruction {
565561
* Holds if (determined by this guard) `op < k` must be `isLessThan` on the edge from
566562
* `pred` to `succ`. If `isLessThan = false` then this implies `op >= k`.
567563
*/
568-
cached
564+
pragma[inline]
569565
predicate ensuresLtEdge(Operand left, int k, IRBlock pred, IRBlock succ, boolean isLessThan) {
570566
exists(AbstractValue value |
571567
compares_lt(valueNumber(this), left, k, isLessThan, value) and
@@ -574,7 +570,6 @@ class IRGuardCondition extends Instruction {
574570
}
575571

576572
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
577-
cached
578573
predicate comparesEq(Operand left, Operand right, int k, boolean areEqual, boolean testIsTrue) {
579574
exists(BooleanValue value |
580575
compares_eq(valueNumber(this), left, right, k, areEqual, value) and
@@ -583,7 +578,6 @@ class IRGuardCondition extends Instruction {
583578
}
584579

585580
/** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */
586-
cached
587581
predicate comparesEq(Operand op, int k, boolean areEqual, AbstractValue value) {
588582
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value)
589583
}
@@ -592,7 +586,7 @@ class IRGuardCondition extends Instruction {
592586
* Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`.
593587
* If `areEqual = false` then this implies `left != right + k`.
594588
*/
595-
cached
589+
pragma[inline]
596590
predicate ensuresEq(Operand left, Operand right, int k, IRBlock block, boolean areEqual) {
597591
exists(AbstractValue value |
598592
compares_eq(valueNumber(this), left, right, k, areEqual, value) and
@@ -604,7 +598,7 @@ class IRGuardCondition extends Instruction {
604598
* Holds if (determined by this guard) `op == k` must be `areEqual` in `block`.
605599
* If `areEqual = false` then this implies `op != k`.
606600
*/
607-
cached
601+
pragma[inline]
608602
predicate ensuresEq(Operand op, int k, IRBlock block, boolean areEqual) {
609603
exists(AbstractValue value |
610604
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value) and
@@ -616,7 +610,7 @@ class IRGuardCondition extends Instruction {
616610
* Holds if (determined by this guard) `left == right + k` must be `areEqual` on the edge from
617611
* `pred` to `succ`. If `areEqual = false` then this implies `left != right + k`.
618612
*/
619-
cached
613+
pragma[inline]
620614
predicate ensuresEqEdge(
621615
Operand left, Operand right, int k, IRBlock pred, IRBlock succ, boolean areEqual
622616
) {
@@ -630,7 +624,7 @@ class IRGuardCondition extends Instruction {
630624
* Holds if (determined by this guard) `op == k` must be `areEqual` on the edge from
631625
* `pred` to `succ`. If `areEqual = false` then this implies `op != k`.
632626
*/
633-
cached
627+
pragma[inline]
634628
predicate ensuresEqEdge(Operand op, int k, IRBlock pred, IRBlock succ, boolean areEqual) {
635629
exists(AbstractValue value |
636630
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value) and

0 commit comments

Comments
 (0)