@@ -324,25 +324,88 @@ module ProductFlow {
324324
325325 private module Flow2 = DataFlow:: GlobalWithState< Config2 > ;
326326
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]
327336 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
330346 ) {
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
334350 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 )
343391 )
344392 }
345393
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+
346409 private predicate localPathStep1 ( Flow1:: PathNode pred , Flow1:: PathNode succ ) {
347410 Flow1:: PathGraph:: edges ( pred , succ ) and
348411 pragma [ only_bind_out ] ( pred .getNode ( ) .getEnclosingCallable ( ) ) =
@@ -474,11 +537,14 @@ module ProductFlow {
474537 private predicate reachable (
475538 Flow1:: PathNode source1 , Flow2:: PathNode source2 , Flow1:: PathNode sink1 , Flow2:: PathNode sink2
476539 ) {
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
482548 )
483549 }
484550 }
0 commit comments