@@ -1519,6 +1519,7 @@ private module Stage3 {
15191519 if fwdFlow ( node , true , _, ap , config ) then returnAp = apSome ( ap ) else returnAp = apNone ( )
15201520 }
15211521
1522+ // TODO: remove
15221523 pragma [ nomagic]
15231524 predicate readCandFwd ( Node node1 , TypedContent tc , Ap ap , Node node2 , Configuration config ) {
15241525 fwdFlowRead ( ap , _, node1 , node2 , _, _, config ) and
@@ -1591,6 +1592,13 @@ private module Stage3 {
15911592 fwdFlow ( ret , true , apSome ( _) , ap , config )
15921593 )
15931594 }
1595+
1596+ predicate readStepCand ( Node node1 , Content c , Node node2 , Configuration config ) {
1597+ exists ( Ap ap |
1598+ revFlow ( node2 , _, _, ap , config ) and
1599+ readStepFwd ( node1 , _, c , node2 , ap , config )
1600+ )
1601+ }
15941602 /* End: Stage 3 logic. */
15951603}
15961604
@@ -1811,6 +1819,12 @@ private module Stage4 {
18111819
18121820 class ApNil = AccessPathApproxNil ;
18131821
1822+ bindingset [ tc, tail]
1823+ private Ap apCons ( TypedContent tc , Ap tail ) { result = push ( tc , tail ) }
1824+
1825+ pragma [ noinline]
1826+ private Content getHeadContent ( Ap ap ) { result = ap .getHead ( ) .getContent ( ) }
1827+
18141828 class ApOption = AccessPathApproxOption ;
18151829
18161830 ApOption apNone ( ) { result = TAccessPathApproxNone ( ) }
@@ -1870,12 +1884,15 @@ private module Stage4 {
18701884 )
18711885 or
18721886 // store
1873- exists ( TypedContent tc | fwdFlowStore ( node , tc , pop ( tc , ap ) , cc , argAp , config ) )
1887+ exists ( TypedContent tc , Ap ap0 |
1888+ fwdFlowStore ( node , tc , ap0 , cc , argAp , config ) and
1889+ ap = apCons ( tc , ap0 )
1890+ )
18741891 or
18751892 // read
1876- exists ( TypedContent tc , AccessPathFront apf |
1877- fwdFlowRead ( node , push ( tc , ap ) , apf , cc , argAp , config ) and
1878- fwdFlowConsCand ( tc , apf , ap , config )
1893+ exists ( Ap ap0 , Content c |
1894+ fwdFlowRead ( ap0 , c , _ , node , cc , argAp , config ) and
1895+ fwdFlowConsCand ( ap0 , c , ap , config )
18791896 )
18801897 or
18811898 // flow into a callable
@@ -1919,11 +1936,12 @@ private module Stage4 {
19191936 }
19201937
19211938 pragma [ nomagic]
1922- private predicate fwdFlowConsCand (
1923- TypedContent tc , AccessPathFront apf , Ap ap , Configuration config
1924- ) {
1925- fwdFlowStore ( _, tc , ap , _, _, config ) and
1926- apf = ap .getFront ( )
1939+ private predicate fwdFlowConsCand ( Ap cons , Content c , Ap tail , Configuration config ) {
1940+ exists ( TypedContent tc |
1941+ fwdFlowStore ( _, tc , tail , _, _, config ) and
1942+ tc .getContent ( ) = c and
1943+ cons = apCons ( tc , tail )
1944+ )
19271945 }
19281946
19291947 pragma [ nomagic]
@@ -1947,23 +1965,13 @@ private module Stage4 {
19471965 )
19481966 }
19491967
1950- pragma [ nomagic]
1951- private predicate fwdFlowRead0 (
1952- Node node1 , TypedContent tc , Ap ap0 , Node node2 , Cc cc , ApOption argAp , Configuration config
1953- ) {
1954- fwdFlow ( node1 , cc , argAp , ap0 , config ) and
1955- Stage3:: readCandFwd ( node1 , tc , ap0 .getFront ( ) , node2 , config )
1956- }
1957-
19581968 pragma [ nomagic]
19591969 private predicate fwdFlowRead (
1960- Node node , Ap ap0 , AccessPathFront apf , Cc cc , ApOption argAp , Configuration config
1970+ Ap ap , Content c , Node node1 , Node node2 , Cc cc , ApOption argAp , Configuration config
19611971 ) {
1962- exists ( Node mid , TypedContent tc |
1963- fwdFlowRead0 ( mid , tc , ap0 , node , cc , argAp , config ) and
1964- Stage3:: revFlow ( node , _, _, apf , unbind ( config ) ) and
1965- stage3consCand ( tc , apf , unbind ( config ) )
1966- )
1972+ fwdFlow ( node1 , cc , argAp , ap , config ) and
1973+ Stage3:: readStepCand ( node1 , c , node2 , config ) and
1974+ getHeadContent ( ap ) = c
19671975 }
19681976
19691977 pragma [ nomagic]
@@ -2025,6 +2033,11 @@ private module Stage4 {
20252033 )
20262034 }
20272035
2036+ private predicate readStepFwd ( Node n1 , Ap ap1 , Content c , Node n2 , Ap ap2 , Configuration config ) {
2037+ fwdFlowRead ( ap1 , c , n1 , n2 , _, _, config ) and
2038+ fwdFlowConsCand ( ap1 , c , ap2 , config )
2039+ }
2040+
20282041 /**
20292042 * Holds if `node` with approximate access path `ap` is part of a path from a
20302043 * source to a sink in the configuration `config`.
@@ -2033,11 +2046,13 @@ private module Stage4 {
20332046 * the enclosing callable in order to reach a sink, and if so, `returnAp`
20342047 * records the approximate access path of the returned value.
20352048 */
2049+ pragma [ nomagic]
20362050 predicate revFlow ( Node node , boolean toReturn , ApOption returnAp , Ap ap , Configuration config ) {
20372051 revFlow0 ( node , toReturn , returnAp , ap , config ) and
20382052 fwdFlow ( node , _, _, ap , config )
20392053 }
20402054
2055+ pragma [ nomagic]
20412056 private predicate revFlow0 (
20422057 Node node , boolean toReturn , ApOption returnAp , Ap ap , Configuration config
20432058 ) {
@@ -2076,15 +2091,15 @@ private module Stage4 {
20762091 )
20772092 or
20782093 // store
2079- exists ( TypedContent tc |
2080- revFlowStore ( tc , node , toReturn , returnAp , ap , config ) and
2081- revFlowConsCand ( tc , ap , config )
2094+ exists ( Ap ap0 , Content c |
2095+ revFlowStore ( ap0 , c , node , toReturn , returnAp , ap , config ) and
2096+ revFlowConsCand ( ap0 , c , ap , config )
20822097 )
20832098 or
20842099 // read
20852100 exists ( Node mid , Ap ap0 |
2086- readFlowFwd ( node , _ , mid , ap , ap0 , config ) and
2087- revFlow ( mid , toReturn , returnAp , ap0 , config )
2101+ revFlow ( mid , toReturn , returnAp , ap0 , config ) and
2102+ readStepFwd ( node , ap , _ , mid , ap0 , config )
20882103 )
20892104 or
20902105 // flow into a callable
@@ -2117,32 +2132,20 @@ private module Stage4 {
21172132
21182133 pragma [ nomagic]
21192134 private predicate revFlowStore (
2120- TypedContent tc , Node node , boolean toReturn , ApOption returnAp , Ap ap , Configuration config
2135+ Ap ap0 , Content c , Node node , boolean toReturn , ApOption returnAp , Ap ap , Configuration config
21212136 ) {
2122- exists ( Node mid , Ap ap0 |
2137+ exists ( Node mid , TypedContent tc |
21232138 storeFlowFwd ( node , tc , mid , ap , ap0 , config ) and
2124- revFlow ( mid , toReturn , returnAp , ap0 , config )
2125- )
2126- }
2127-
2128- pragma [ nomagic]
2129- private predicate readFlowFwd (
2130- Node node1 , TypedContent tc , Node node2 , Ap ap , Ap ap0 , Configuration config
2131- ) {
2132- exists ( AccessPathFrontHead apf |
2133- Stage3:: readCandFwd ( node1 , tc , apf , node2 , config ) and
2134- apf = ap .getFront ( ) and
2135- fwdFlowRead ( node2 , ap , _, _, _, config ) and
2136- ap0 = pop ( tc , ap ) and
2137- fwdFlowConsCand ( tc , _, ap0 , unbind ( config ) )
2139+ revFlow ( mid , toReturn , returnAp , ap0 , config ) and
2140+ tc .getContent ( ) = c
21382141 )
21392142 }
21402143
21412144 pragma [ nomagic]
2142- predicate revFlowConsCand ( TypedContent tc , Ap ap , Configuration config ) {
2143- exists ( Node n , Node mid |
2144- revFlow ( mid , _, _, ap , config ) and
2145- readFlowFwd ( n , tc , mid , _ , ap , config )
2145+ predicate revFlowConsCand ( Ap cons , Content c , Ap tail , Configuration config ) {
2146+ exists ( Node mid |
2147+ revFlow ( mid , _, _, tail , config ) and
2148+ readStepFwd ( _ , cons , c , mid , tail , config )
21462149 )
21472150 }
21482151
@@ -2197,6 +2200,13 @@ private module Stage4 {
21972200 /* End: Stage 4 logic. */
21982201}
21992202
2203+ private predicate stage4consCand ( TypedContent tc , AccessPathApprox apa , Configuration config ) {
2204+ exists ( AccessPathApprox apa0 |
2205+ Stage4:: revFlowConsCand ( apa0 , _, apa , config ) and
2206+ apa0 .getHead ( ) = tc
2207+ )
2208+ }
2209+
22002210bindingset [ conf, result ]
22012211private Configuration unbind ( Configuration conf ) { result >= conf and result <= conf }
22022212
@@ -2273,8 +2283,8 @@ private int count1to2unfold(AccessPathApproxCons1 apa, Configuration config) {
22732283 len = apa .len ( ) and
22742284 result =
22752285 strictcount ( AccessPathFront apf |
2276- Stage4 :: revFlowConsCand ( tc ,
2277- any ( AccessPathApprox ap | ap . getFront ( ) = apf and ap . len ( ) = len - 1 ) , config )
2286+ stage4consCand ( tc , any ( AccessPathApprox ap | ap . getFront ( ) = apf and ap . len ( ) = len - 1 ) ,
2287+ config )
22782288 )
22792289 )
22802290}
@@ -2301,7 +2311,7 @@ private predicate expensiveLen1to2unfolding(AccessPathApproxCons1 apa, Configura
23012311private AccessPathApprox getATail ( AccessPathApprox apa , Configuration config ) {
23022312 exists ( TypedContent head |
23032313 apa .pop ( head ) = result and
2304- Stage4 :: revFlowConsCand ( head , result , config )
2314+ stage4consCand ( head , result , config )
23052315 )
23062316}
23072317
@@ -2519,7 +2529,7 @@ private class AccessPathCons2 extends AccessPath, TAccessPathCons2 {
25192529 override TypedContent getHead ( ) { result = head1 }
25202530
25212531 override AccessPath getTail ( ) {
2522- Stage4 :: revFlowConsCand ( head1 , result .getApprox ( ) , _) and
2532+ stage4consCand ( head1 , result .getApprox ( ) , _) and
25232533 result .getHead ( ) = head2 and
25242534 result .length ( ) = len - 1
25252535 }
@@ -2550,7 +2560,7 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
25502560 override TypedContent getHead ( ) { result = head }
25512561
25522562 override AccessPath getTail ( ) {
2553- Stage4 :: revFlowConsCand ( head , result .getApprox ( ) , _) and result .length ( ) = len - 1
2563+ stage4consCand ( head , result .getApprox ( ) , _) and result .length ( ) = len - 1
25542564 }
25552565
25562566 override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head ) }
0 commit comments