@@ -1241,6 +1241,12 @@ private module Stage3 {
12411241
12421242 class ApNil = AccessPathFrontNil ;
12431243
1244+ bindingset [ tc, tail]
1245+ private Ap apCons ( TypedContent tc , Ap tail ) { result .getHead ( ) = tc and exists ( tail ) }
1246+
1247+ pragma [ noinline]
1248+ private Content getHeadContent ( Ap ap ) { result = ap .getHead ( ) .getContent ( ) }
1249+
12441250 class ApOption = AccessPathFrontOption ;
12451251
12461252 ApOption apNone ( ) { result = TAccessPathFrontNone ( ) }
@@ -1301,15 +1307,15 @@ private module Stage3 {
13011307 )
13021308 or
13031309 // store
1304- exists ( TypedContent tc |
1305- fwdFlowStore ( node , tc , _ , cc , argAp , config ) and
1306- ap . headUsesContent ( tc )
1310+ exists ( TypedContent tc , Ap ap0 |
1311+ fwdFlowStore ( node , tc , ap0 , cc , argAp , config ) and
1312+ ap = apCons ( tc , ap0 )
13071313 )
13081314 or
13091315 // read
1310- exists ( TypedContent tc |
1311- fwdFlowRead ( tc , node , cc , argAp , config ) and
1312- fwdFlowConsCand ( tc , ap , config ) and
1316+ exists ( Ap ap0 , Content c |
1317+ fwdFlowRead ( ap0 , c , _ , node , cc , argAp , config ) and
1318+ fwdFlowConsCand ( ap0 , c , ap , config ) and
13131319 Stage2:: revFlow ( node , _, _, unbindBool ( ap .toBoolNonEmpty ( ) ) , unbind ( config ) )
13141320 )
13151321 or
@@ -1346,25 +1352,21 @@ private module Stage3 {
13461352 }
13471353
13481354 pragma [ nomagic]
1349- private predicate fwdFlowConsCand ( TypedContent tc , Ap ap , Configuration config ) {
1350- fwdFlowStore ( _, tc , ap , _, _, config )
1355+ private predicate fwdFlowConsCand ( Ap cons , Content c , Ap tail , Configuration config ) {
1356+ exists ( TypedContent tc |
1357+ fwdFlowStore ( _, tc , tail , _, _, config ) and
1358+ tc .getContent ( ) = c and
1359+ cons = apCons ( tc , tail )
1360+ )
13511361 }
13521362
13531363 pragma [ nomagic]
1354- private predicate fwdFlowRead0 (
1355- Node node1 , TypedContent tc , Content c , Node node2 , Cc cc , ApOption argAp ,
1356- AccessPathFrontHead ap , Configuration config
1364+ private predicate fwdFlowRead (
1365+ Ap ap , Content c , Node node1 , Node node2 , Cc cc , ApOption argAp , Configuration config
13571366 ) {
13581367 fwdFlow ( node1 , cc , argAp , ap , config ) and
13591368 readCand2 ( node1 , c , node2 , config ) and
1360- ap .headUsesContent ( tc )
1361- }
1362-
1363- pragma [ nomagic]
1364- private predicate fwdFlowRead (
1365- TypedContent tc , Node node , Cc cc , ApOption argAp , Configuration config
1366- ) {
1367- fwdFlowRead0 ( _, tc , tc .getContent ( ) , node , cc , argAp , _, config )
1369+ getHeadContent ( ap ) = c
13681370 }
13691371
13701372 pragma [ nomagic]
@@ -1411,6 +1413,11 @@ private module Stage3 {
14111413 )
14121414 }
14131415
1416+ private predicate readStepFwd ( Node n1 , Ap ap1 , Content c , Node n2 , Ap ap2 , Configuration config ) {
1417+ fwdFlowRead ( ap1 , c , n1 , n2 , _, _, config ) and
1418+ fwdFlowConsCand ( ap1 , c , ap2 , config )
1419+ }
1420+
14141421 /**
14151422 * Holds if `node` with access path front `ap` is part of a path from a
14161423 * source to a sink in the configuration `config`.
@@ -1464,15 +1471,15 @@ private module Stage3 {
14641471 )
14651472 or
14661473 // store
1467- exists ( TypedContent tc |
1468- revFlowStore ( node , tc , ap , toReturn , returnAp , config ) and
1469- revFlowConsCand ( tc , ap , config )
1474+ exists ( Ap ap0 , Content c |
1475+ revFlowStore ( ap0 , c , node , ap , toReturn , returnAp , config ) and
1476+ revFlowConsCand ( ap0 , c , ap , config )
14701477 )
14711478 or
14721479 // read
1473- exists ( TypedContent tc , Ap ap0 |
1474- revFlowRead ( node , tc , ap , toReturn , returnAp , ap0 , config ) and
1475- fwdFlowConsCand ( tc , ap0 , config )
1480+ exists ( Node mid , Ap ap0 |
1481+ revFlow ( mid , toReturn , returnAp , ap0 , config ) and
1482+ readStepFwd ( node , ap , _ , mid , ap0 , config )
14761483 )
14771484 or
14781485 // flow into a callable
@@ -1494,35 +1501,29 @@ private module Stage3 {
14941501
14951502 pragma [ nomagic]
14961503 predicate readCandFwd ( Node node1 , TypedContent tc , Ap ap , Node node2 , Configuration config ) {
1497- fwdFlowRead0 ( node1 , tc , tc .getContent ( ) , node2 , _, _, ap , config )
1498- }
1499-
1500- pragma [ nomagic]
1501- private predicate revFlowRead (
1502- Node node , TypedContent tc , Ap ap , boolean toReturn , ApOption returnAp , Ap apf0 ,
1503- Configuration config
1504- ) {
1505- exists ( Node mid |
1506- readCandFwd ( node , tc , ap , mid , config ) and
1507- revFlow ( mid , toReturn , returnAp , apf0 , config )
1508- )
1504+ fwdFlowRead ( ap , _, node1 , node2 , _, _, config ) and
1505+ ap .headUsesContent ( tc )
15091506 }
15101507
15111508 pragma [ nomagic]
15121509 private predicate revFlowStore (
1513- Node node , TypedContent tc , Ap ap , boolean toReturn , ApOption returnAp , Configuration config
1510+ Ap ap0 , Content c , Node node , Ap ap , boolean toReturn , ApOption returnAp , Configuration config
15141511 ) {
1515- exists ( Node mid |
1512+ exists ( Node mid , TypedContent tc |
15161513 fwdFlow ( node , _, _, ap , config ) and
15171514 storeCand2 ( node , tc , mid , _, unbind ( config ) ) and
1518- revFlow ( mid , toReturn , returnAp , TFrontHead ( tc ) , unbind ( config ) )
1515+ revFlow ( mid , toReturn , returnAp , ap0 , unbind ( config ) ) and
1516+ ap0 = TFrontHead ( tc ) and
1517+ tc .getContent ( ) = c
15191518 )
15201519 }
15211520
15221521 pragma [ nomagic]
1523- predicate revFlowConsCand ( TypedContent tc , Ap ap , Configuration config ) {
1524- fwdFlowConsCand ( tc , ap , config ) and
1525- revFlowRead ( _, tc , _, _, _, ap , config )
1522+ predicate revFlowConsCand ( Ap cons , Content c , Ap tail , Configuration config ) {
1523+ exists ( Node mid |
1524+ revFlow ( mid , _, _, tail , config ) and
1525+ readStepFwd ( _, cons , c , mid , tail , config )
1526+ )
15261527 }
15271528
15281529 pragma [ nomagic]
@@ -1573,6 +1574,13 @@ private module Stage3 {
15731574 /* End: Stage 3 logic. */
15741575}
15751576
1577+ private predicate stage3consCand ( TypedContent tc , AccessPathFront apf , Configuration config ) {
1578+ exists ( AccessPathFront apf0 |
1579+ Stage3:: revFlowConsCand ( apf0 , _, apf , config ) and
1580+ apf0 .getHead ( ) = tc
1581+ )
1582+ }
1583+
15761584/**
15771585 * Holds if `argApf` is recorded as the summary context for flow reaching `node`
15781586 * and remains relevant for the following pruning stage.
@@ -1590,7 +1598,7 @@ private predicate flowCandSummaryCtx(Node node, AccessPathFront argApf, Configur
15901598 */
15911599private predicate expensiveLen2unfolding ( TypedContent tc , Configuration config ) {
15921600 exists ( int tails , int nodes , int apLimit , int tupleLimit |
1593- tails = strictcount ( AccessPathFront apf | Stage3 :: revFlowConsCand ( tc , apf , config ) ) and
1601+ tails = strictcount ( AccessPathFront apf | stage3consCand ( tc , apf , config ) ) and
15941602 nodes =
15951603 strictcount ( Node n |
15961604 Stage3:: revFlow ( n , _, _, any ( AccessPathFrontHead apf | apf .headUsesContent ( tc ) ) , config )
@@ -1606,11 +1614,11 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
16061614private newtype TAccessPathApprox =
16071615 TNil ( DataFlowType t ) or
16081616 TConsNil ( TypedContent tc , DataFlowType t ) {
1609- Stage3 :: revFlowConsCand ( tc , TFrontNil ( t ) , _) and
1617+ stage3consCand ( tc , TFrontNil ( t ) , _) and
16101618 not expensiveLen2unfolding ( tc , _)
16111619 } or
16121620 TConsCons ( TypedContent tc1 , TypedContent tc2 , int len ) {
1613- Stage3 :: revFlowConsCand ( tc1 , TFrontHead ( tc2 ) , _) and
1621+ stage3consCand ( tc1 , TFrontHead ( tc2 ) , _) and
16141622 len in [ 2 .. accessPathLimit ( ) ] and
16151623 not expensiveLen2unfolding ( tc1 , _)
16161624 } or
@@ -1740,7 +1748,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 {
17401748 override AccessPathApprox pop ( TypedContent head ) {
17411749 head = tc and
17421750 (
1743- exists ( TypedContent tc2 | Stage3 :: revFlowConsCand ( tc , TFrontHead ( tc2 ) , _) |
1751+ exists ( TypedContent tc2 | stage3consCand ( tc , TFrontHead ( tc2 ) , _) |
17441752 result = TConsCons ( tc2 , _, len - 1 )
17451753 or
17461754 len = 2 and
@@ -1751,7 +1759,7 @@ private class AccessPathApproxCons1 extends AccessPathApproxCons, TCons1 {
17511759 or
17521760 exists ( DataFlowType t |
17531761 len = 1 and
1754- Stage3 :: revFlowConsCand ( tc , TFrontNil ( t ) , _) and
1762+ stage3consCand ( tc , TFrontNil ( t ) , _) and
17551763 result = TNil ( t )
17561764 )
17571765 )
@@ -1914,7 +1922,7 @@ private module Stage4 {
19141922 ) {
19151923 exists ( AccessPathFront apf |
19161924 storeCand ( mid , tc , node , apf0 , apf , config ) and
1917- Stage3 :: revFlowConsCand ( tc , apf0 , config ) and
1925+ stage3consCand ( tc , apf0 , config ) and
19181926 Stage3:: revFlow ( node , _, _, apf , unbind ( config ) )
19191927 )
19201928 }
@@ -1934,7 +1942,7 @@ private module Stage4 {
19341942 exists ( Node mid , TypedContent tc |
19351943 fwdFlowRead0 ( mid , tc , ap0 , node , cc , argAp , config ) and
19361944 Stage3:: revFlow ( node , _, _, apf , unbind ( config ) ) and
1937- Stage3 :: revFlowConsCand ( tc , apf , unbind ( config ) )
1945+ stage3consCand ( tc , apf , unbind ( config ) )
19381946 )
19391947 }
19401948
0 commit comments