@@ -324,25 +324,88 @@ module ProductFlow {
324
324
325
325
private module Flow2 = DataFlow:: GlobalWithState< Config2 > ;
326
326
327
+ private predicate isSourcePair ( Flow1:: PathNode node1 , Flow2:: PathNode node2 ) {
328
+ Config:: isSourcePair ( node1 .getNode ( ) , node1 .getState ( ) , node2 .getNode ( ) , node2 .getState ( ) )
329
+ }
330
+
331
+ private predicate isSinkPair ( Flow1:: PathNode node1 , Flow2:: PathNode node2 ) {
332
+ Config:: isSinkPair ( node1 .getNode ( ) , node1 .getState ( ) , node2 .getNode ( ) , node2 .getState ( ) )
333
+ }
334
+
335
+ pragma [ assume_small_delta]
327
336
pragma [ nomagic]
328
- private predicate reachableInterprocEntry (
329
- Flow1:: PathNode source1 , Flow2:: PathNode source2 , Flow1:: PathNode node1 , Flow2:: PathNode node2
337
+ private predicate fwdReachableInterprocEntry ( Flow1:: PathNode node1 , Flow2:: PathNode node2 ) {
338
+ isSourcePair ( node1 , node2 )
339
+ or
340
+ fwdIsSuccessor ( _, _, node1 , node2 )
341
+ }
342
+
343
+ pragma [ nomagic]
344
+ private predicate fwdIsSuccessorExit (
345
+ Flow1:: PathNode mid1 , Flow2:: PathNode mid2 , Flow1:: PathNode succ1 , Flow2:: PathNode succ2
330
346
) {
331
- Config :: isSourcePair ( node1 . getNode ( ) , node1 . getState ( ) , node2 . getNode ( ) , node2 . getState ( ) ) and
332
- node1 = source1 and
333
- node2 = source2
347
+ isSinkPair ( mid1 , mid2 ) and
348
+ succ1 = mid1 and
349
+ succ2 = mid2
334
350
or
335
- exists (
336
- Flow1:: PathNode midEntry1 , Flow2:: PathNode midEntry2 , Flow1:: PathNode midExit1 ,
337
- Flow2:: PathNode midExit2
338
- |
339
- reachableInterprocEntry ( source1 , source2 , midEntry1 , midEntry2 ) and
340
- interprocEdgePair ( midExit1 , midExit2 , node1 , node2 ) and
341
- localPathStep1 * ( midEntry1 , midExit1 ) and
342
- localPathStep2 * ( midEntry2 , midExit2 )
351
+ interprocEdgePair ( mid1 , mid2 , succ1 , succ2 )
352
+ }
353
+
354
+ private predicate fwdIsSuccessor1 (
355
+ Flow1:: PathNode pred1 , Flow2:: PathNode pred2 , Flow1:: PathNode mid1 , Flow2:: PathNode mid2 ,
356
+ Flow1:: PathNode succ1 , Flow2:: PathNode succ2
357
+ ) {
358
+ fwdReachableInterprocEntry ( pred1 , pred2 ) and
359
+ localPathStep1 * ( pred1 , mid1 ) and
360
+ fwdIsSuccessorExit ( pragma [ only_bind_into ] ( mid1 ) , pragma [ only_bind_into ] ( mid2 ) , succ1 , succ2 )
361
+ }
362
+
363
+ private predicate fwdIsSuccessor2 (
364
+ Flow1:: PathNode pred1 , Flow2:: PathNode pred2 , Flow1:: PathNode mid1 , Flow2:: PathNode mid2 ,
365
+ Flow1:: PathNode succ1 , Flow2:: PathNode succ2
366
+ ) {
367
+ fwdReachableInterprocEntry ( pred1 , pred2 ) and
368
+ localPathStep2 * ( pred2 , mid2 ) and
369
+ fwdIsSuccessorExit ( pragma [ only_bind_into ] ( mid1 ) , pragma [ only_bind_into ] ( mid2 ) , succ1 , succ2 )
370
+ }
371
+
372
+ pragma [ assume_small_delta]
373
+ private predicate fwdIsSuccessor (
374
+ Flow1:: PathNode pred1 , Flow2:: PathNode pred2 , Flow1:: PathNode succ1 , Flow2:: PathNode succ2
375
+ ) {
376
+ exists ( Flow1:: PathNode mid1 , Flow2:: PathNode mid2 |
377
+ fwdIsSuccessor1 ( pred1 , pred2 , mid1 , mid2 , succ1 , succ2 ) and
378
+ fwdIsSuccessor2 ( pred1 , pred2 , mid1 , mid2 , succ1 , succ2 )
379
+ )
380
+ }
381
+
382
+ pragma [ assume_small_delta]
383
+ pragma [ nomagic]
384
+ private predicate revReachableInterprocEntry ( Flow1:: PathNode node1 , Flow2:: PathNode node2 ) {
385
+ fwdReachableInterprocEntry ( node1 , node2 ) and
386
+ isSinkPair ( node1 , node2 )
387
+ or
388
+ exists ( Flow1:: PathNode succ1 , Flow2:: PathNode succ2 |
389
+ revReachableInterprocEntry ( succ1 , succ2 ) and
390
+ fwdIsSuccessor ( node1 , node2 , succ1 , succ2 )
343
391
)
344
392
}
345
393
394
+ private newtype TNodePair =
395
+ TMkNodePair ( Flow1:: PathNode node1 , Flow2:: PathNode node2 ) {
396
+ revReachableInterprocEntry ( node1 , node2 )
397
+ }
398
+
399
+ private predicate pathSucc ( TNodePair n1 , TNodePair n2 ) {
400
+ exists ( Flow1:: PathNode n11 , Flow2:: PathNode n12 , Flow1:: PathNode n21 , Flow2:: PathNode n22 |
401
+ n1 = TMkNodePair ( n11 , n12 ) and
402
+ n2 = TMkNodePair ( n21 , n22 ) and
403
+ fwdIsSuccessor ( n11 , n12 , n21 , n22 )
404
+ )
405
+ }
406
+
407
+ private predicate pathSuccPlus ( TNodePair n1 , TNodePair n2 ) = fastTC( pathSucc / 2 ) ( n1 , n2 )
408
+
346
409
private predicate localPathStep1 ( Flow1:: PathNode pred , Flow1:: PathNode succ ) {
347
410
Flow1:: PathGraph:: edges ( pred , succ ) and
348
411
pragma [ only_bind_out ] ( pred .getNode ( ) .getEnclosingCallable ( ) ) =
@@ -474,11 +537,14 @@ module ProductFlow {
474
537
private predicate reachable (
475
538
Flow1:: PathNode source1 , Flow2:: PathNode source2 , Flow1:: PathNode sink1 , Flow2:: PathNode sink2
476
539
) {
477
- exists ( Flow1:: PathNode mid1 , Flow2:: PathNode mid2 |
478
- reachableInterprocEntry ( source1 , source2 , mid1 , mid2 ) and
479
- Config:: isSinkPair ( sink1 .getNode ( ) , sink1 .getState ( ) , sink2 .getNode ( ) , sink2 .getState ( ) ) and
480
- localPathStep1 * ( mid1 , sink1 ) and
481
- localPathStep2 * ( mid2 , sink2 )
540
+ isSourcePair ( source1 , source2 ) and
541
+ isSinkPair ( sink1 , sink2 ) and
542
+ exists ( TNodePair n1 , TNodePair n2 |
543
+ n1 = TMkNodePair ( source1 , source2 ) and
544
+ n2 = TMkNodePair ( sink1 , sink2 )
545
+ |
546
+ pathSuccPlus ( n1 , n2 ) or
547
+ n1 = n2
482
548
)
483
549
}
484
550
}
0 commit comments