@@ -1005,8 +1005,9 @@ private module Stage1 implements StageSig {
10051005 }
10061006
10071007 pragma [ nomagic]
1008- predicate returnMayFlowThrough ( RetNodeEx ret , Configuration config ) {
1009- throughFlowNodeCand ( ret , config )
1008+ predicate returnMayFlowThrough ( RetNodeEx ret , ReturnPosition pos , Configuration config ) {
1009+ throughFlowNodeCand ( ret , config ) and
1010+ pos = ret .getReturnPosition ( )
10101011 }
10111012
10121013 pragma [ nomagic]
@@ -1065,9 +1066,10 @@ private predicate viableReturnPosOutNodeCand1(
10651066 */
10661067pragma [ nomagic]
10671068private predicate flowOutOfCallNodeCand1 (
1068- DataFlowCall call , RetNodeEx ret , NodeEx out , Configuration config
1069+ DataFlowCall call , RetNodeEx ret , ReturnPosition pos , NodeEx out , Configuration config
10691070) {
1070- viableReturnPosOutNodeCand1 ( call , ret .getReturnPosition ( ) , out , config ) and
1071+ viableReturnPosOutNodeCand1 ( call , pos , out , config ) and
1072+ pos = ret .getReturnPosition ( ) and
10711073 Stage1:: revFlow ( ret , config ) and
10721074 not outBarrier ( ret , config ) and
10731075 not inBarrier ( out , config )
@@ -1103,7 +1105,7 @@ private predicate flowIntoCallNodeCand1(
11031105private int branch ( NodeEx n1 , Configuration conf ) {
11041106 result =
11051107 strictcount ( NodeEx n |
1106- flowOutOfCallNodeCand1 ( _, n1 , n , conf ) or flowIntoCallNodeCand1 ( _, n1 , n , conf )
1108+ flowOutOfCallNodeCand1 ( _, n1 , _ , n , conf ) or flowIntoCallNodeCand1 ( _, n1 , n , conf )
11071109 )
11081110}
11091111
@@ -1115,7 +1117,7 @@ private int branch(NodeEx n1, Configuration conf) {
11151117private int join ( NodeEx n2 , Configuration conf ) {
11161118 result =
11171119 strictcount ( NodeEx n |
1118- flowOutOfCallNodeCand1 ( _, n , n2 , conf ) or flowIntoCallNodeCand1 ( _, n , n2 , conf )
1120+ flowOutOfCallNodeCand1 ( _, n , _ , n2 , conf ) or flowIntoCallNodeCand1 ( _, n , n2 , conf )
11191121 )
11201122}
11211123
@@ -1128,12 +1130,13 @@ private int join(NodeEx n2, Configuration conf) {
11281130 */
11291131pragma [ nomagic]
11301132private predicate flowOutOfCallNodeCand1 (
1131- DataFlowCall call , RetNodeEx ret , NodeEx out , boolean allowsFieldFlow , Configuration config
1133+ DataFlowCall call , RetNodeEx ret , ReturnPosition pos , NodeEx out , boolean allowsFieldFlow ,
1134+ Configuration config
11321135) {
1133- flowOutOfCallNodeCand1 ( call , ret , out , config ) and
1136+ flowOutOfCallNodeCand1 ( call , ret , pos , out , pragma [ only_bind_into ] ( config ) ) and
11341137 exists ( int b , int j |
1135- b = branch ( ret , config ) and
1136- j = join ( out , config ) and
1138+ b = branch ( ret , pragma [ only_bind_into ] ( config ) ) and
1139+ j = join ( out , pragma [ only_bind_into ] ( config ) ) and
11371140 if b .minimum ( j ) <= config .fieldFlowBranchLimit ( )
11381141 then allowsFieldFlow = true
11391142 else allowsFieldFlow = false
@@ -1171,7 +1174,7 @@ private signature module StageSig {
11711174
11721175 predicate parameterMayFlowThrough ( ParamNodeEx p , Ap ap , Configuration config ) ;
11731176
1174- predicate returnMayFlowThrough ( RetNodeEx ret , Configuration config ) ;
1177+ predicate returnMayFlowThrough ( RetNodeEx ret , ReturnPosition pos , Configuration config ) ;
11751178
11761179 predicate storeStepCand (
11771180 NodeEx node1 , Ap ap1 , TypedContent tc , NodeEx node2 , DataFlowType contentType ,
@@ -1237,7 +1240,8 @@ private module MkStage<StageSig PrevStage> {
12371240 ) ;
12381241
12391242 predicate flowOutOfCall (
1240- DataFlowCall call , RetNodeEx ret , NodeEx out , boolean allowsFieldFlow , Configuration config
1243+ DataFlowCall call , RetNodeEx ret , ReturnPosition pos , NodeEx out , boolean allowsFieldFlow ,
1244+ Configuration config
12411245 ) ;
12421246
12431247 predicate flowIntoCall (
@@ -1262,13 +1266,16 @@ private module MkStage<StageSig PrevStage> {
12621266
12631267 pragma [ nomagic]
12641268 private predicate flowThroughOutOfCall (
1265- DataFlowCall call , CcCall ccc , RetNodeEx ret , NodeEx out , boolean allowsFieldFlow ,
1266- Configuration config
1269+ DataFlowCall call , CcCall ccc , RetNodeEx ret , ReturnKindExt kind , NodeEx out ,
1270+ boolean allowsFieldFlow , Configuration config
12671271 ) {
1268- flowOutOfCall ( call , ret , out , allowsFieldFlow , pragma [ only_bind_into ] ( config ) ) and
1269- PrevStage:: callMayFlowThroughRev ( call , pragma [ only_bind_into ] ( config ) ) and
1270- PrevStage:: returnMayFlowThrough ( ret , pragma [ only_bind_into ] ( config ) ) and
1271- matchesCall ( ccc , call )
1272+ exists ( ReturnPosition pos |
1273+ flowOutOfCall ( call , ret , pos , out , allowsFieldFlow , pragma [ only_bind_into ] ( config ) ) and
1274+ kind = pos .getKind ( ) and
1275+ PrevStage:: callMayFlowThroughRev ( call , pragma [ only_bind_into ] ( config ) ) and
1276+ PrevStage:: returnMayFlowThrough ( ret , pos , pragma [ only_bind_into ] ( config ) ) and
1277+ matchesCall ( ccc , call )
1278+ )
12721279 }
12731280
12741281 /**
@@ -1429,7 +1436,7 @@ private module MkStage<StageSig PrevStage> {
14291436 DataFlowCallable inner
14301437 |
14311438 fwdFlow ( ret , state , innercc , summaryCtx , argAp , ap , config ) and
1432- flowOutOfCall ( call , ret , out , allowsFieldFlow , config ) and
1439+ flowOutOfCall ( call , ret , _ , out , allowsFieldFlow , config ) and
14331440 inner = ret .getEnclosingCallable ( ) and
14341441 ccOut = getCallContextReturn ( inner , call , innercc ) and
14351442 if allowsFieldFlow = false then ap instanceof ApNil else any ( )
@@ -1441,11 +1448,11 @@ private module MkStage<StageSig PrevStage> {
14411448 DataFlowCall call , NodeEx out , FlowState state , ParamNode summaryCtx , Ap argAp , Ap ap ,
14421449 Configuration config
14431450 ) {
1444- exists ( RetNodeEx ret , boolean allowsFieldFlow , CcCall ccc |
1451+ exists ( RetNodeEx ret , ReturnKindExt kind , boolean allowsFieldFlow , CcCall ccc |
14451452 fwdFlow ( ret , state , ccc , TParamNodeSome ( summaryCtx ) , apSome ( argAp ) , ap , config ) and
1446- flowThroughOutOfCall ( call , ccc , ret , out , allowsFieldFlow , config ) and
1453+ flowThroughOutOfCall ( call , ccc , ret , kind , out , allowsFieldFlow , config ) and
14471454 ( if allowsFieldFlow = false then ap instanceof ApNil else any ( ) ) and
1448- parameterFlowThroughAllowed ( summaryCtx , ret . getKind ( ) )
1455+ parameterFlowThroughAllowed ( summaryCtx , kind )
14491456 )
14501457 }
14511458
@@ -1483,10 +1490,12 @@ private module MkStage<StageSig PrevStage> {
14831490
14841491 pragma [ nomagic]
14851492 private predicate returnFlowsThrough (
1486- RetNodeEx ret , FlowState state , CcCall ccc , ParamNode p , Ap argAp , Ap ap , Configuration config
1493+ RetNodeEx ret , ReturnPosition pos , FlowState state , CcCall ccc , ParamNode p , Ap argAp , Ap ap ,
1494+ Configuration config
14871495 ) {
14881496 fwdFlow ( ret , state , ccc , TParamNodeSome ( p ) , apSome ( argAp ) , ap , config ) and
1489- parameterFlowThroughAllowed ( p , ret .getKind ( ) )
1497+ pos = ret .getReturnPosition ( ) and
1498+ parameterFlowThroughAllowed ( p , pos .getKind ( ) )
14901499 }
14911500
14921501 pragma [ nomagic]
@@ -1496,7 +1505,7 @@ private module MkStage<StageSig PrevStage> {
14961505 flowIntoCall ( call , pragma [ only_bind_into ] ( arg ) , pragma [ only_bind_into ] ( p ) , allowsFieldFlow ,
14971506 pragma [ only_bind_into ] ( config ) ) and
14981507 fwdFlow ( arg , _, _, _, _, _, pragma [ only_bind_into ] ( config ) ) and
1499- returnFlowsThrough ( _, _, _, p .asNode ( ) , _, _, pragma [ only_bind_into ] ( config ) )
1508+ returnFlowsThrough ( _, _, _, _ , p .asNode ( ) , _, _, pragma [ only_bind_into ] ( config ) )
15001509 }
15011510
15021511 /**
@@ -1592,13 +1601,15 @@ private module MkStage<StageSig PrevStage> {
15921601 )
15931602 or
15941603 // flow out of a callable
1595- revFlowOut ( _, node , state , _, _, ap , config ) and
1596- if returnFlowsThrough ( node , state , _, _, _, ap , config )
1597- then (
1598- returnCtx = TReturnCtxMaybeFlowThrough ( node .( RetNodeEx ) .getReturnPosition ( ) ) and
1599- returnAp = apSome ( ap )
1600- ) else (
1601- returnCtx = TReturnCtxNoFlowThrough ( ) and returnAp = apNone ( )
1604+ exists ( ReturnPosition pos |
1605+ revFlowOut ( _, node , pos , state , _, _, ap , config ) and
1606+ if returnFlowsThrough ( node , pos , state , _, _, _, ap , config )
1607+ then (
1608+ returnCtx = TReturnCtxMaybeFlowThrough ( pos ) and
1609+ returnAp = apSome ( ap )
1610+ ) else (
1611+ returnCtx = TReturnCtxNoFlowThrough ( ) and returnAp = apNone ( )
1612+ )
16021613 )
16031614 }
16041615
@@ -1627,12 +1638,12 @@ private module MkStage<StageSig PrevStage> {
16271638
16281639 pragma [ nomagic]
16291640 private predicate revFlowOut (
1630- DataFlowCall call , RetNodeEx ret , FlowState state , ReturnCtx returnCtx , ApOption returnAp ,
1631- Ap ap , Configuration config
1641+ DataFlowCall call , RetNodeEx ret , ReturnPosition pos , FlowState state , ReturnCtx returnCtx ,
1642+ ApOption returnAp , Ap ap , Configuration config
16321643 ) {
16331644 exists ( NodeEx out , boolean allowsFieldFlow |
16341645 revFlow ( out , state , returnCtx , returnAp , ap , config ) and
1635- flowOutOfCall ( call , ret , out , allowsFieldFlow , config ) and
1646+ flowOutOfCall ( call , ret , pos , out , allowsFieldFlow , config ) and
16361647 if allowsFieldFlow = false then ap instanceof ApNil else any ( )
16371648 )
16381649 }
@@ -1672,9 +1683,8 @@ private module MkStage<StageSig PrevStage> {
16721683 Configuration config
16731684 ) {
16741685 exists ( RetNodeEx ret , FlowState state , CcCall ccc |
1675- revFlowOut ( call , ret , state , returnCtx , returnAp , ap , config ) and
1676- returnFlowsThrough ( ret , state , ccc , _, _, ap , config ) and
1677- pos = ret .getReturnPosition ( ) and
1686+ revFlowOut ( call , ret , pos , state , returnCtx , returnAp , ap , config ) and
1687+ returnFlowsThrough ( ret , pos , state , ccc , _, _, ap , config ) and
16781688 matchesCall ( ccc , call )
16791689 )
16801690 }
@@ -1755,17 +1765,17 @@ private module MkStage<StageSig PrevStage> {
17551765
17561766 pragma [ nomagic]
17571767 predicate parameterMayFlowThrough ( ParamNodeEx p , Ap ap , Configuration config ) {
1758- exists ( RetNodeEx ret |
1759- returnFlowsThrough ( ret , _, _, p .asNode ( ) , ap , _, config ) and
1760- parameterFlowsThroughRev ( p , ap , ret . getReturnPosition ( ) , config )
1768+ exists ( RetNodeEx ret , ReturnPosition pos |
1769+ returnFlowsThrough ( ret , pos , _, _, p .asNode ( ) , ap , _, config ) and
1770+ parameterFlowsThroughRev ( p , ap , pos , config )
17611771 )
17621772 }
17631773
17641774 pragma [ nomagic]
1765- predicate returnMayFlowThrough ( RetNodeEx ret , Configuration config ) {
1775+ predicate returnMayFlowThrough ( RetNodeEx ret , ReturnPosition pos , Configuration config ) {
17661776 exists ( ParamNodeEx p , Ap ap |
1767- returnFlowsThrough ( ret , _, _, p .asNode ( ) , ap , _, config ) and
1768- parameterFlowsThroughRev ( p , ap , ret . getReturnPosition ( ) , config )
1777+ returnFlowsThrough ( ret , pos , _, _, p .asNode ( ) , ap , _, config ) and
1778+ parameterFlowsThroughRev ( p , ap , pos , config )
17691779 )
17701780 }
17711781
@@ -1946,7 +1956,7 @@ private module Stage2Param implements MkStage<Stage1>::StageParam {
19461956 exists ( lcc )
19471957 }
19481958
1949- predicate flowOutOfCall = flowOutOfCallNodeCand1 / 5 ;
1959+ predicate flowOutOfCall = flowOutOfCallNodeCand1 / 6 ;
19501960
19511961 predicate flowIntoCall = flowIntoCallNodeCand1 / 5 ;
19521962
@@ -1982,9 +1992,10 @@ private module Stage2 implements StageSig {
19821992
19831993pragma [ nomagic]
19841994private predicate flowOutOfCallNodeCand2 (
1985- DataFlowCall call , RetNodeEx node1 , NodeEx node2 , boolean allowsFieldFlow , Configuration config
1995+ DataFlowCall call , RetNodeEx node1 , ReturnPosition pos , NodeEx node2 , boolean allowsFieldFlow ,
1996+ Configuration config
19861997) {
1987- flowOutOfCallNodeCand1 ( call , node1 , node2 , allowsFieldFlow , config ) and
1998+ flowOutOfCallNodeCand1 ( call , node1 , pos , node2 , allowsFieldFlow , config ) and
19881999 Stage2:: revFlow ( node2 , pragma [ only_bind_into ] ( config ) ) and
19892000 Stage2:: revFlowAlias ( node1 , pragma [ only_bind_into ] ( config ) )
19902001}
@@ -2053,7 +2064,7 @@ private module LocalFlowBigStep {
20532064 jumpStep ( node , next , config ) or
20542065 additionalJumpStep ( node , next , config ) or
20552066 flowIntoCallNodeCand2 ( _, node , next , _, config ) or
2056- flowOutOfCallNodeCand2 ( _, node , next , _, config ) or
2067+ flowOutOfCallNodeCand2 ( _, node , _ , next , _, config ) or
20572068 Stage2:: storeStepCand ( node , _, _, next , _, config ) or
20582069 Stage2:: readStepCand ( node , _, next , config )
20592070 )
@@ -2194,7 +2205,7 @@ private module Stage3Param implements MkStage<Stage2>::StageParam {
21942205 localFlowBigStep ( node1 , state1 , node2 , state2 , preservesValue , ap , config , _) and exists ( lcc )
21952206 }
21962207
2197- predicate flowOutOfCall = flowOutOfCallNodeCand2 / 5 ;
2208+ predicate flowOutOfCall = flowOutOfCallNodeCand2 / 6 ;
21982209
21992210 predicate flowIntoCall = flowIntoCallNodeCand2 / 5 ;
22002211
@@ -2500,10 +2511,11 @@ private module Stage4Param implements MkStage<Stage3>::StageParam {
25002511
25012512 pragma [ nomagic]
25022513 predicate flowOutOfCall (
2503- DataFlowCall call , RetNodeEx node1 , NodeEx node2 , boolean allowsFieldFlow , Configuration config
2514+ DataFlowCall call , RetNodeEx node1 , ReturnPosition pos , NodeEx node2 , boolean allowsFieldFlow ,
2515+ Configuration config
25042516 ) {
25052517 exists ( FlowState state |
2506- flowOutOfCallNodeCand2 ( call , node1 , node2 , allowsFieldFlow , config ) and
2518+ flowOutOfCallNodeCand2 ( call , node1 , pos , node2 , allowsFieldFlow , config ) and
25072519 PrevStage:: revFlow ( node2 , pragma [ only_bind_into ] ( state ) , _, pragma [ only_bind_into ] ( config ) ) and
25082520 PrevStage:: revFlowAlias ( node1 , pragma [ only_bind_into ] ( state ) , _,
25092521 pragma [ only_bind_into ] ( config ) )
0 commit comments