@@ -1489,10 +1489,6 @@ private module MkStage<StageSig PrevStage> {
14891489 parameterFlowThroughAllowed ( p , ret .getKind ( ) )
14901490 }
14911491
1492- predicate returnMayFlowThrough ( RetNodeEx ret , Configuration config ) {
1493- returnFlowsThrough ( ret , _, _, _, _, _, config )
1494- }
1495-
14961492 pragma [ nomagic]
14971493 private predicate flowThroughIntoCall (
14981494 DataFlowCall call , ArgNodeEx arg , ParamNodeEx p , boolean allowsFieldFlow , Configuration config
@@ -1507,52 +1503,58 @@ private module MkStage<StageSig PrevStage> {
15071503 * Holds if `node` with access path `ap` is part of a path from a source to a
15081504 * sink in the configuration `config`.
15091505 *
1510- * The Boolean `toReturn ` records whether the node must be returned from the
1511- * enclosing callable in order to reach a sink, and if so, `returnAp` records
1512- * the access path of the returned value.
1506+ * The parameter `returnCtx ` records whether (and how) the node must be returned
1507+ * from the enclosing callable in order to reach a sink, and if so, `returnAp`
1508+ * records the access path of the returned value.
15131509 */
15141510 pragma [ nomagic]
15151511 additional predicate revFlow (
1516- NodeEx node , FlowState state , boolean toReturn , ApOption returnAp , Ap ap , Configuration config
1512+ NodeEx node , FlowState state , ReturnCtx returnCtx , ApOption returnAp , Ap ap ,
1513+ Configuration config
15171514 ) {
1518- revFlow0 ( node , state , toReturn , returnAp , ap , config ) and
1515+ revFlow0 ( node , state , returnCtx , returnAp , ap , config ) and
15191516 fwdFlow ( node , state , _, _, _, ap , config )
15201517 }
15211518
15221519 pragma [ nomagic]
15231520 private predicate revFlow0 (
1524- NodeEx node , FlowState state , boolean toReturn , ApOption returnAp , Ap ap , Configuration config
1521+ NodeEx node , FlowState state , ReturnCtx returnCtx , ApOption returnAp , Ap ap ,
1522+ Configuration config
15251523 ) {
15261524 fwdFlow ( node , state , _, _, _, ap , config ) and
15271525 sinkNode ( node , state , config ) and
1528- ( if hasSinkCallCtx ( config ) then toReturn = true else toReturn = false ) and
1526+ (
1527+ if hasSinkCallCtx ( config )
1528+ then returnCtx = TReturnCtxNoFlowThrough ( )
1529+ else returnCtx = TReturnCtxNone ( )
1530+ ) and
15291531 returnAp = apNone ( ) and
15301532 ap instanceof ApNil
15311533 or
15321534 exists ( NodeEx mid , FlowState state0 |
15331535 localStep ( node , state , mid , state0 , true , _, config , _) and
1534- revFlow ( mid , state0 , toReturn , returnAp , ap , config )
1536+ revFlow ( mid , state0 , returnCtx , returnAp , ap , config )
15351537 )
15361538 or
15371539 exists ( NodeEx mid , FlowState state0 , ApNil nil |
15381540 fwdFlow ( node , pragma [ only_bind_into ] ( state ) , _, _, _, ap , pragma [ only_bind_into ] ( config ) ) and
15391541 localStep ( node , pragma [ only_bind_into ] ( state ) , mid , state0 , false , _, config , _) and
1540- revFlow ( mid , state0 , toReturn , returnAp , nil , pragma [ only_bind_into ] ( config ) ) and
1542+ revFlow ( mid , state0 , returnCtx , returnAp , nil , pragma [ only_bind_into ] ( config ) ) and
15411543 ap instanceof ApNil
15421544 )
15431545 or
15441546 exists ( NodeEx mid |
15451547 jumpStep ( node , mid , config ) and
15461548 revFlow ( mid , state , _, _, ap , config ) and
1547- toReturn = false and
1549+ returnCtx = TReturnCtxNone ( ) and
15481550 returnAp = apNone ( )
15491551 )
15501552 or
15511553 exists ( NodeEx mid , ApNil nil |
15521554 fwdFlow ( node , _, _, _, _, ap , pragma [ only_bind_into ] ( config ) ) and
15531555 additionalJumpStep ( node , mid , config ) and
15541556 revFlow ( pragma [ only_bind_into ] ( mid ) , state , _, _, nil , pragma [ only_bind_into ] ( config ) ) and
1555- toReturn = false and
1557+ returnCtx = TReturnCtxNone ( ) and
15561558 returnAp = apNone ( ) and
15571559 ap instanceof ApNil
15581560 )
@@ -1562,47 +1564,50 @@ private module MkStage<StageSig PrevStage> {
15621564 additionalJumpStateStep ( node , state , mid , state0 , config ) and
15631565 revFlow ( pragma [ only_bind_into ] ( mid ) , pragma [ only_bind_into ] ( state0 ) , _, _, nil ,
15641566 pragma [ only_bind_into ] ( config ) ) and
1565- toReturn = false and
1567+ returnCtx = TReturnCtxNone ( ) and
15661568 returnAp = apNone ( ) and
15671569 ap instanceof ApNil
15681570 )
15691571 or
15701572 // store
15711573 exists ( Ap ap0 , Content c |
1572- revFlowStore ( ap0 , c , ap , node , state , _, _, toReturn , returnAp , config ) and
1574+ revFlowStore ( ap0 , c , ap , node , state , _, _, returnCtx , returnAp , config ) and
15731575 revFlowConsCand ( ap0 , c , ap , config )
15741576 )
15751577 or
15761578 // read
15771579 exists ( NodeEx mid , Ap ap0 |
1578- revFlow ( mid , state , toReturn , returnAp , ap0 , config ) and
1580+ revFlow ( mid , state , returnCtx , returnAp , ap0 , config ) and
15791581 readStepFwd ( node , ap , _, mid , ap0 , config )
15801582 )
15811583 or
15821584 // flow into a callable
15831585 revFlowInNotToReturn ( node , state , returnAp , ap , config ) and
1584- toReturn = false
1586+ returnCtx = TReturnCtxNone ( )
15851587 or
15861588 // flow through a callable
1587- exists ( DataFlowCall call , Ap returnAp0 |
1588- revFlowInToReturn ( call , node , state , returnAp0 , ap , config ) and
1589- revFlowIsReturned ( call , toReturn , returnAp , returnAp0 , config )
1589+ exists ( DataFlowCall call , ReturnPosition returnPos0 , Ap returnAp0 |
1590+ revFlowInToReturn ( call , node , state , returnPos0 , returnAp0 , ap , config ) and
1591+ revFlowIsReturned ( call , returnCtx , returnAp , returnPos0 , returnAp0 , config )
15901592 )
15911593 or
15921594 // flow out of a callable
15931595 revFlowOut ( _, node , state , _, _, ap , config ) and
1594- toReturn = true and
15951596 if returnFlowsThrough ( node , state , _, _, _, ap , config )
1596- then returnAp = apSome ( ap )
1597- else returnAp = apNone ( )
1597+ then (
1598+ returnCtx = TReturnCtxMaybeFlowThrough ( node .( RetNodeEx ) .getReturnPosition ( ) ) and
1599+ returnAp = apSome ( ap )
1600+ ) else (
1601+ returnCtx = TReturnCtxNoFlowThrough ( ) and returnAp = apNone ( )
1602+ )
15981603 }
15991604
16001605 pragma [ nomagic]
16011606 private predicate revFlowStore (
16021607 Ap ap0 , Content c , Ap ap , NodeEx node , FlowState state , TypedContent tc , NodeEx mid ,
1603- boolean toReturn , ApOption returnAp , Configuration config
1608+ ReturnCtx returnCtx , ApOption returnAp , Configuration config
16041609 ) {
1605- revFlow ( mid , state , toReturn , returnAp , ap0 , config ) and
1610+ revFlow ( mid , state , returnCtx , returnAp , ap0 , config ) and
16061611 storeStepFwd ( node , ap , tc , mid , ap0 , config ) and
16071612 tc .getContent ( ) = c
16081613 }
@@ -1622,11 +1627,11 @@ private module MkStage<StageSig PrevStage> {
16221627
16231628 pragma [ nomagic]
16241629 private predicate revFlowOut (
1625- DataFlowCall call , RetNodeEx ret , FlowState state , boolean toReturn , ApOption returnAp , Ap ap ,
1626- Configuration config
1630+ DataFlowCall call , RetNodeEx ret , FlowState state , ReturnCtx returnCtx , ApOption returnAp ,
1631+ Ap ap , Configuration config
16271632 ) {
16281633 exists ( NodeEx out , boolean allowsFieldFlow |
1629- revFlow ( out , state , toReturn , returnAp , ap , config ) and
1634+ revFlow ( out , state , returnCtx , returnAp , ap , config ) and
16301635 flowOutOfCall ( call , ret , out , allowsFieldFlow , config ) and
16311636 if allowsFieldFlow = false then ap instanceof ApNil else any ( )
16321637 )
@@ -1637,20 +1642,22 @@ private module MkStage<StageSig PrevStage> {
16371642 ArgNodeEx arg , FlowState state , ApOption returnAp , Ap ap , Configuration config
16381643 ) {
16391644 exists ( ParamNodeEx p , boolean allowsFieldFlow |
1640- revFlow ( p , state , false , returnAp , ap , config ) and
1645+ revFlow ( p , state , TReturnCtxNone ( ) , returnAp , ap , config ) and
16411646 flowIntoCall ( _, arg , p , allowsFieldFlow , config ) and
16421647 if allowsFieldFlow = false then ap instanceof ApNil else any ( )
16431648 )
16441649 }
16451650
16461651 pragma [ nomagic]
16471652 private predicate revFlowInToReturn (
1648- DataFlowCall call , ArgNodeEx arg , FlowState state , Ap returnAp , Ap ap , Configuration config
1653+ DataFlowCall call , ArgNodeEx arg , FlowState state , ReturnPosition returnPos , Ap returnAp ,
1654+ Ap ap , Configuration config
16491655 ) {
16501656 exists ( ParamNodeEx p , boolean allowsFieldFlow |
1651- revFlow ( p , state , true , apSome ( returnAp ) , ap , config ) and
1657+ revFlow ( p , state , TReturnCtxMaybeFlowThrough ( returnPos ) , apSome ( returnAp ) , ap , config ) and
16521658 flowThroughIntoCall ( call , arg , p , allowsFieldFlow , config ) and
1653- if allowsFieldFlow = false then ap instanceof ApNil else any ( )
1659+ ( if allowsFieldFlow = false then ap instanceof ApNil else any ( ) ) and
1660+ parameterFlowThroughAllowed ( p .asNode ( ) , returnPos .getKind ( ) )
16541661 )
16551662 }
16561663
@@ -1661,11 +1668,13 @@ private module MkStage<StageSig PrevStage> {
16611668 */
16621669 pragma [ nomagic]
16631670 private predicate revFlowIsReturned (
1664- DataFlowCall call , boolean toReturn , ApOption returnAp , Ap ap , Configuration config
1671+ DataFlowCall call , ReturnCtx returnCtx , ApOption returnAp , ReturnPosition pos , Ap ap ,
1672+ Configuration config
16651673 ) {
16661674 exists ( RetNodeEx ret , FlowState state , CcCall ccc |
1667- revFlowOut ( call , ret , state , toReturn , returnAp , ap , config ) and
1675+ revFlowOut ( call , ret , state , returnCtx , returnAp , ap , config ) and
16681676 returnFlowsThrough ( ret , state , ccc , _, _, ap , config ) and
1677+ pos = ret .getReturnPosition ( ) and
16691678 matchesCall ( ccc , call )
16701679 )
16711680 }
@@ -1736,34 +1745,39 @@ private module MkStage<StageSig PrevStage> {
17361745 validAp ( ap , config )
17371746 }
17381747
1739- pragma [ noinline ]
1740- private predicate parameterFlow (
1741- ParamNodeEx p , Ap ap , Ap ap0 , DataFlowCallable c , Configuration config
1748+ pragma [ nomagic ]
1749+ private predicate parameterFlowsThroughRev (
1750+ ParamNodeEx p , Ap ap , ReturnPosition returnPos , Configuration config
17421751 ) {
1743- revFlow ( p , _, true , apSome ( ap0 ) , ap , config ) and
1744- c = p . getEnclosingCallable ( )
1752+ revFlow ( p , _, TReturnCtxMaybeFlowThrough ( returnPos ) , apSome ( _ ) , ap , config ) and
1753+ parameterFlowThroughAllowed ( p . asNode ( ) , returnPos . getKind ( ) )
17451754 }
17461755
1756+ pragma [ nomagic]
17471757 predicate parameterMayFlowThrough ( ParamNodeEx p , Ap ap , Configuration config ) {
1748- exists ( DataFlowCallable c , RetNodeEx ret , FlowState state , Ap ap0 , ParameterPosition pos |
1749- parameterFlow ( p , ap , ap0 , c , config ) and
1750- c = ret .getEnclosingCallable ( ) and
1751- revFlow ( pragma [ only_bind_into ] ( ret ) , pragma [ only_bind_into ] ( state ) , true , apSome ( _) ,
1752- pragma [ only_bind_into ] ( ap0 ) , pragma [ only_bind_into ] ( config ) ) and
1753- returnFlowsThrough ( ret , state , _, p .asNode ( ) , ap , ap0 , config ) and
1754- p .getPosition ( ) = pos and
1755- parameterFlowThroughAllowed ( p .asNode ( ) , ret .getKind ( ) )
1758+ exists ( RetNodeEx ret |
1759+ returnFlowsThrough ( ret , _, _, p .asNode ( ) , ap , _, config ) and
1760+ parameterFlowsThroughRev ( p , ap , ret .getReturnPosition ( ) , config )
1761+ )
1762+ }
1763+
1764+ pragma [ nomagic]
1765+ predicate returnMayFlowThrough ( RetNodeEx ret , Configuration config ) {
1766+ exists ( ParamNodeEx p , Ap ap |
1767+ returnFlowsThrough ( ret , _, _, p .asNode ( ) , ap , _, config ) and
1768+ parameterFlowsThroughRev ( p , ap , ret .getReturnPosition ( ) , config )
17561769 )
17571770 }
17581771
17591772 pragma [ nomagic]
17601773 predicate callMayFlowThroughRev ( DataFlowCall call , Configuration config ) {
17611774 exists (
1762- Ap returnAp0 , ArgNodeEx arg , FlowState state , boolean toReturn , ApOption returnAp , Ap ap
1775+ ReturnPosition returnPos0 , Ap returnAp0 , ArgNodeEx arg , FlowState state ,
1776+ ReturnCtx returnCtx , ApOption returnAp , Ap ap
17631777 |
1764- revFlow ( arg , state , toReturn , returnAp , ap , config ) and
1765- revFlowInToReturn ( call , arg , state , returnAp0 , ap , config ) and
1766- revFlowIsReturned ( call , toReturn , returnAp , returnAp0 , config )
1778+ revFlow ( arg , state , returnCtx , returnAp , ap , config ) and
1779+ revFlowInToReturn ( call , arg , state , returnPos0 , returnAp0 , ap , config ) and
1780+ revFlowIsReturned ( call , returnCtx , returnAp , returnPos0 , returnAp0 , config )
17671781 )
17681782 }
17691783
@@ -1786,8 +1800,8 @@ private module MkStage<StageSig PrevStage> {
17861800 conscand = count ( TypedContent f0 , Ap ap | consCand ( f0 , ap , config ) ) and
17871801 states = count ( FlowState state | revFlow ( _, state , _, _, _, config ) ) and
17881802 tuples =
1789- count ( NodeEx n , FlowState state , boolean b , ApOption retAp , Ap ap |
1790- revFlow ( n , state , b , retAp , ap , config )
1803+ count ( NodeEx n , FlowState state , ReturnCtx returnCtx , ApOption retAp , Ap ap |
1804+ revFlow ( n , state , returnCtx , retAp , ap , config )
17911805 )
17921806 }
17931807 /* End: Stage logic. */
@@ -2250,7 +2264,7 @@ private predicate flowCandSummaryCtx(
22502264 NodeEx node , FlowState state , AccessPathFront argApf , Configuration config
22512265) {
22522266 exists ( AccessPathFront apf |
2253- Stage3:: revFlow ( node , state , true , _, apf , config ) and
2267+ Stage3:: revFlow ( node , state , TReturnCtxMaybeFlowThrough ( _ ) , _, apf , config ) and
22542268 Stage3:: fwdFlow ( node , state , any ( Stage3:: CcCall ccc ) , _, TAccessPathFrontSome ( argApf ) , apf ,
22552269 config )
22562270 )
@@ -2530,7 +2544,7 @@ private predicate nodeMayUseSummary0(
25302544) {
25312545 exists ( AccessPathApprox apa0 |
25322546 Stage4:: parameterMayFlowThrough ( p , _, _) and
2533- Stage4:: revFlow ( n , state , true , _, apa0 , config ) and
2547+ Stage4:: revFlow ( n , state , TReturnCtxMaybeFlowThrough ( _ ) , _, apa0 , config ) and
25342548 Stage4:: fwdFlow ( n , state , any ( CallContextCall ccc ) , TParamNodeSome ( p .asNode ( ) ) ,
25352549 TAccessPathApproxSome ( apa ) , apa0 , config )
25362550 )
0 commit comments