@@ -72,6 +72,20 @@ abstract private class GuardConditionImpl extends Expr {
72
72
*/
73
73
abstract predicate valueControls ( BasicBlock controlled , AbstractValue v ) ;
74
74
75
+ /**
76
+ * Holds if the control-flow edge `(pred, succ)` may be taken only if
77
+ * the value of this condition is `v`.
78
+ */
79
+ abstract predicate valueControlsEdge ( BasicBlock pred , BasicBlock succ , AbstractValue v ) ;
80
+
81
+ /**
82
+ * Holds if the control-flow edge `(pred, succ)` may be taken only if
83
+ * this the value of this condition is `testIsTrue`.
84
+ */
85
+ final predicate controlsEdge ( BasicBlock pred , BasicBlock succ , boolean testIsTrue ) {
86
+ this .valueControlsEdge ( pred , succ , any ( BooleanValue bv | bv .getValue ( ) = testIsTrue ) )
87
+ }
88
+
75
89
/**
76
90
* Holds if this condition controls `controlled`, meaning that `controlled` is only
77
91
* entered if the value of this condition is `testIsTrue`.
@@ -175,6 +189,58 @@ abstract private class GuardConditionImpl extends Expr {
175
189
*/
176
190
pragma [ inline]
177
191
abstract predicate ensuresEq ( Expr e , int k , BasicBlock block , boolean areEqual ) ;
192
+
193
+ /**
194
+ * Holds if (determined by this guard) `left == right + k` must be `areEqual` on the edge from
195
+ * `pred` to `succ`. If `areEqual = false` then this implies `left != right + k`.
196
+ */
197
+ pragma [ inline]
198
+ final predicate ensuresEqEdge (
199
+ Expr left , Expr right , int k , BasicBlock pred , BasicBlock succ , boolean areEqual
200
+ ) {
201
+ exists ( boolean testIsTrue |
202
+ this .comparesEq ( left , right , k , areEqual , testIsTrue ) and
203
+ this .controlsEdge ( pred , succ , testIsTrue )
204
+ )
205
+ }
206
+
207
+ /**
208
+ * Holds if (determined by this guard) `e == k` must be `areEqual` on the edge from
209
+ * `pred` to `succ`. If `areEqual = false` then this implies `e != k`.
210
+ */
211
+ pragma [ inline]
212
+ final predicate ensuresEqEdge ( Expr e , int k , BasicBlock pred , BasicBlock succ , boolean areEqual ) {
213
+ exists ( AbstractValue v |
214
+ this .comparesEq ( e , k , areEqual , v ) and
215
+ this .valueControlsEdge ( pred , succ , v )
216
+ )
217
+ }
218
+
219
+ /**
220
+ * Holds if (determined by this guard) `left < right + k` must be `isLessThan` on the edge from
221
+ * `pred` to `succ`. If `isLessThan = false` then this implies `left >= right + k`.
222
+ */
223
+ pragma [ inline]
224
+ final predicate ensuresLtEdge (
225
+ Expr left , Expr right , int k , BasicBlock pred , BasicBlock succ , boolean isLessThan
226
+ ) {
227
+ exists ( boolean testIsTrue |
228
+ this .comparesLt ( left , right , k , isLessThan , testIsTrue ) and
229
+ this .controlsEdge ( pred , succ , testIsTrue )
230
+ )
231
+ }
232
+
233
+ /**
234
+ * Holds if (determined by this guard) `e < k` must be `isLessThan` on the edge from
235
+ * `pred` to `succ`. If `isLessThan = false` then this implies `e >= k`.
236
+ */
237
+ pragma [ inline]
238
+ final predicate ensuresLtEdge ( Expr e , int k , BasicBlock pred , BasicBlock succ , boolean isLessThan ) {
239
+ exists ( AbstractValue v |
240
+ this .comparesLt ( e , k , isLessThan , v ) and
241
+ this .valueControlsEdge ( pred , succ , v )
242
+ )
243
+ }
178
244
}
179
245
180
246
final class GuardCondition = GuardConditionImpl ;
@@ -187,6 +253,16 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
187
253
this .( BinaryLogicalOperation ) .getAnOperand ( ) instanceof GuardCondition
188
254
}
189
255
256
+ override predicate valueControlsEdge ( BasicBlock pred , BasicBlock succ , AbstractValue v ) {
257
+ exists ( BinaryLogicalOperation binop , GuardCondition lhs , GuardCondition rhs |
258
+ this = binop and
259
+ lhs = binop .getLeftOperand ( ) and
260
+ rhs = binop .getRightOperand ( ) and
261
+ lhs .valueControlsEdge ( pred , succ , v ) and
262
+ rhs .valueControlsEdge ( pred , succ , v )
263
+ )
264
+ }
265
+
190
266
override predicate valueControls ( BasicBlock controlled , AbstractValue v ) {
191
267
exists ( BinaryLogicalOperation binop , GuardCondition lhs , GuardCondition rhs |
192
268
this = binop and
@@ -274,6 +350,25 @@ private predicate controlsBlock(IRGuardCondition ir, BasicBlock controlled, Abst
274
350
)
275
351
}
276
352
353
+ /**
354
+ * Holds if `ir` controls the `(pred, succ)` edge, meaning that the edge
355
+ * `(pred, succ)` is only taken if the value of this condition is `v`. This
356
+ * helper predicate does not necessarily hold for binary logical operations
357
+ * like `&&` and `||`.
358
+ * See the detailed explanation on predicate `controlsEdge`.
359
+ */
360
+ private predicate controlsEdge (
361
+ IRGuardCondition ir , BasicBlock pred , BasicBlock succ , AbstractValue v
362
+ ) {
363
+ exists ( IRBlock irPred , IRBlock irSucc |
364
+ ir .valueControlsEdge ( irPred , irSucc , v ) and
365
+ nonExcludedIRAndBasicBlock ( irPred , pred ) and
366
+ nonExcludedIRAndBasicBlock ( irSucc , succ ) and
367
+ not isUnreachedBlock ( irPred ) and
368
+ not isUnreachedBlock ( irSucc )
369
+ )
370
+ }
371
+
277
372
private class GuardConditionFromNotExpr extends GuardConditionImpl {
278
373
IRGuardCondition ir ;
279
374
@@ -295,6 +390,10 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl {
295
390
controlsBlock ( ir , controlled , v .getDualValue ( ) )
296
391
}
297
392
393
+ override predicate valueControlsEdge ( BasicBlock pred , BasicBlock succ , AbstractValue v ) {
394
+ controlsEdge ( ir , pred , succ , v .getDualValue ( ) )
395
+ }
396
+
298
397
pragma [ inline]
299
398
override predicate comparesLt ( Expr left , Expr right , int k , boolean isLessThan , boolean testIsTrue ) {
300
399
exists ( Instruction li , Instruction ri |
@@ -383,6 +482,10 @@ private class GuardConditionFromIR extends GuardConditionImpl {
383
482
controlsBlock ( ir , controlled , v )
384
483
}
385
484
485
+ override predicate valueControlsEdge ( BasicBlock pred , BasicBlock succ , AbstractValue v ) {
486
+ controlsEdge ( ir , pred , succ , v )
487
+ }
488
+
386
489
pragma [ inline]
387
490
override predicate comparesLt ( Expr left , Expr right , int k , boolean isLessThan , boolean testIsTrue ) {
388
491
exists ( Instruction li , Instruction ri |
0 commit comments