@@ -190,6 +190,8 @@ module MakeImpl<InputSig Lang> {
190190
191191 private class ArgNodeEx extends NodeEx {
192192 ArgNodeEx ( ) { this .asNode ( ) instanceof ArgNode }
193+
194+ DataFlowCall getCall ( ) { this .asNode ( ) .( ArgNode ) .argumentOf ( result , _) }
193195 }
194196
195197 private class ParamNodeEx extends NodeEx {
@@ -1145,11 +1147,20 @@ module MakeImpl<InputSig Lang> {
11451147
11461148 class LocalCc ;
11471149
1148- bindingset [ call, c, outercc]
1149- CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c , Cc outercc ) ;
1150+ DataFlowCallable viableImplCallContextReduced ( DataFlowCall call , CcCall ctx ) ;
1151+
1152+ bindingset [ call, ctx]
1153+ predicate viableImplNotCallContextReduced ( DataFlowCall call , Cc ctx ) ;
1154+
1155+ bindingset [ call, c]
1156+ CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c ) ;
11501157
1151- bindingset [ call, c, innercc]
1152- CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call , Cc innercc ) ;
1158+ DataFlowCallable viableImplCallContextReducedReverse ( DataFlowCall call , CcNoCall ctx ) ;
1159+
1160+ predicate viableImplNotCallContextReducedReverse ( CcNoCall ctx ) ;
1161+
1162+ bindingset [ call, c]
1163+ CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call ) ;
11531164
11541165 bindingset [ node, cc]
11551166 LocalCc getLocalCc ( NodeEx node , Cc cc ) ;
@@ -1191,21 +1202,24 @@ module MakeImpl<InputSig Lang> {
11911202
11921203 pragma [ nomagic]
11931204 private predicate flowIntoCallApa (
1194- DataFlowCall call , ArgNodeEx arg , ParamNodeEx p , boolean allowsFieldFlow , ApApprox apa
1205+ DataFlowCall call , DataFlowCallable c , ArgNodeEx arg , ParamNodeEx p ,
1206+ boolean allowsFieldFlow , ApApprox apa
11951207 ) {
11961208 flowIntoCall ( call , arg , p , allowsFieldFlow ) and
11971209 PrevStage:: revFlowAp ( p , pragma [ only_bind_into ] ( apa ) ) and
1198- PrevStage:: revFlowAp ( arg , pragma [ only_bind_into ] ( apa ) )
1210+ PrevStage:: revFlowAp ( arg , pragma [ only_bind_into ] ( apa ) ) and
1211+ c = p .getEnclosingCallable ( )
11991212 }
12001213
12011214 pragma [ nomagic]
12021215 private predicate flowOutOfCallApa (
1203- DataFlowCall call , RetNodeEx ret , ReturnKindExt kind , NodeEx out , boolean allowsFieldFlow ,
1204- ApApprox apa
1216+ DataFlowCall call , DataFlowCallable c , RetNodeEx ret , ReturnKindExt kind , NodeEx out ,
1217+ boolean allowsFieldFlow , ApApprox apa
12051218 ) {
12061219 flowOutOfCall ( call , ret , kind , out , allowsFieldFlow ) and
12071220 PrevStage:: revFlowAp ( out , pragma [ only_bind_into ] ( apa ) ) and
1208- PrevStage:: revFlowAp ( ret , pragma [ only_bind_into ] ( apa ) )
1221+ PrevStage:: revFlowAp ( ret , pragma [ only_bind_into ] ( apa ) ) and
1222+ c = ret .getEnclosingCallable ( )
12091223 }
12101224
12111225 pragma [ nomagic]
@@ -1214,7 +1228,7 @@ module MakeImpl<InputSig Lang> {
12141228 ApApprox argApa , ApApprox apa
12151229 ) {
12161230 exists ( ReturnKindExt kind |
1217- flowOutOfCallApa ( call , ret , kind , out , allowsFieldFlow , apa ) and
1231+ flowOutOfCallApa ( call , _ , ret , kind , out , allowsFieldFlow , apa ) and
12181232 PrevStage:: callMayFlowThroughRev ( call ) and
12191233 PrevStage:: returnMayFlowThrough ( ret , argApa , apa , kind ) and
12201234 matchesCall ( ccc , call )
@@ -1332,16 +1346,7 @@ module MakeImpl<InputSig Lang> {
13321346 )
13331347 or
13341348 // flow out of a callable
1335- exists (
1336- DataFlowCall call , RetNodeEx ret , boolean allowsFieldFlow , CcNoCall innercc ,
1337- DataFlowCallable inner
1338- |
1339- fwdFlow ( ret , state , innercc , summaryCtx , argT , argAp , t , ap , apa ) and
1340- flowOutOfCallApa ( call , ret , _, node , allowsFieldFlow , apa ) and
1341- inner = ret .getEnclosingCallable ( ) and
1342- cc = getCallContextReturn ( inner , call , innercc ) and
1343- if allowsFieldFlow = false then ap instanceof ApNil else any ( )
1344- )
1349+ fwdFlowOut ( node , state , cc , summaryCtx , argT , argAp , t , ap , apa )
13451350 or
13461351 // flow through a callable
13471352 exists (
@@ -1408,15 +1413,115 @@ module MakeImpl<InputSig Lang> {
14081413 )
14091414 }
14101415
1416+ bindingset [ call, ctx]
1417+ pragma [ inline_late]
1418+ private DataFlowCallable viableImplCallContextReducedInlineLate (
1419+ DataFlowCall call , CcCall ctx
1420+ ) {
1421+ result = viableImplCallContextReduced ( call , ctx )
1422+ }
1423+
1424+ bindingset [ arg, ctx]
1425+ pragma [ inline_late]
1426+ private DataFlowCallable viableImplCallContextReducedInlineLate (
1427+ DataFlowCall call , ArgNodeEx arg , CcCall ctx
1428+ ) {
1429+ call = arg .getCall ( ) and
1430+ result = viableImplCallContextReducedInlineLate ( call , ctx )
1431+ }
1432+
1433+ bindingset [ call]
1434+ pragma [ inline_late]
1435+ private predicate flowIntoCallApaInlineLate (
1436+ DataFlowCall call , DataFlowCallable c , ArgNodeEx arg , ParamNodeEx p ,
1437+ boolean allowsFieldFlow , ApApprox apa
1438+ ) {
1439+ flowIntoCallApa ( call , c , arg , p , allowsFieldFlow , apa )
1440+ }
1441+
1442+ bindingset [ call, ctx]
1443+ pragma [ inline_late]
1444+ private predicate viableImplNotCallContextReducedInlineLate ( DataFlowCall call , Cc ctx ) {
1445+ viableImplNotCallContextReduced ( call , ctx )
1446+ }
1447+
1448+ bindingset [ arg, outercc]
1449+ pragma [ inline_late]
1450+ private predicate viableImplArgNotCallContextReduced (
1451+ DataFlowCall call , ArgNodeEx arg , Cc outercc
1452+ ) {
1453+ call = arg .getCall ( ) and
1454+ viableImplNotCallContextReducedInlineLate ( call , outercc )
1455+ }
1456+
14111457 pragma [ nomagic]
14121458 private predicate fwdFlowIn (
14131459 DataFlowCall call , ParamNodeEx p , FlowState state , Cc outercc , CcCall innercc ,
14141460 ParamNodeOption summaryCtx , TypOption argT , ApOption argAp , Typ t , Ap ap , ApApprox apa
14151461 ) {
1416- exists ( ArgNodeEx arg , boolean allowsFieldFlow |
1462+ exists ( ArgNodeEx arg , boolean allowsFieldFlow , DataFlowCallable inner |
14171463 fwdFlow ( arg , state , outercc , summaryCtx , argT , argAp , t , ap , apa ) and
1418- flowIntoCallApa ( call , arg , p , allowsFieldFlow , apa ) and
1419- innercc = getCallContextCall ( call , p .getEnclosingCallable ( ) , outercc ) and
1464+ (
1465+ inner = viableImplCallContextReducedInlineLate ( call , arg , outercc )
1466+ or
1467+ viableImplArgNotCallContextReduced ( call , arg , outercc )
1468+ ) and
1469+ flowIntoCallApaInlineLate ( call , inner , arg , p , allowsFieldFlow , apa )
1470+ |
1471+ innercc = getCallContextCall ( call , inner ) and
1472+ if allowsFieldFlow = false then ap instanceof ApNil else any ( )
1473+ )
1474+ }
1475+
1476+ bindingset [ ctx, result ]
1477+ pragma [ inline_late]
1478+ private DataFlowCallable viableImplCallContextReducedReverseInlineLate (
1479+ DataFlowCall call , CcNoCall ctx
1480+ ) {
1481+ result = viableImplCallContextReducedReverse ( call , ctx )
1482+ }
1483+
1484+ bindingset [ call]
1485+ pragma [ inline_late]
1486+ private predicate flowOutOfCallApaInlineLate (
1487+ DataFlowCall call , DataFlowCallable c , RetNodeEx ret , NodeEx out , boolean allowsFieldFlow ,
1488+ ApApprox apa
1489+ ) {
1490+ flowOutOfCallApa ( call , c , ret , _, out , allowsFieldFlow , apa )
1491+ }
1492+
1493+ bindingset [ c, ret, apa, innercc]
1494+ pragma [ inline_late]
1495+ pragma [ noopt]
1496+ private predicate flowOutOfCallApaNotCallContextReduced (
1497+ DataFlowCall call , DataFlowCallable c , RetNodeEx ret , NodeEx out , boolean allowsFieldFlow ,
1498+ ApApprox apa , CcNoCall innercc
1499+ ) {
1500+ viableImplNotCallContextReducedReverse ( innercc ) and
1501+ flowOutOfCallApa ( call , c , ret , _, out , allowsFieldFlow , apa )
1502+ }
1503+
1504+ // inline to reduce number of iterations
1505+ pragma [ inline]
1506+ private predicate fwdFlowOut (
1507+ NodeEx out , FlowState state , CcNoCall outercc , ParamNodeOption summaryCtx , TypOption argT ,
1508+ ApOption argAp , Typ t , Ap ap , ApApprox apa
1509+ ) {
1510+ exists (
1511+ DataFlowCall call , RetNodeEx ret , boolean allowsFieldFlow , CcNoCall innercc ,
1512+ DataFlowCallable inner
1513+ |
1514+ fwdFlow ( ret , state , innercc , summaryCtx , argT , argAp , t , ap , apa ) and
1515+ inner = ret .getEnclosingCallable ( ) and
1516+ (
1517+ inner = viableImplCallContextReducedReverseInlineLate ( call , innercc ) and
1518+ flowOutOfCallApaInlineLate ( call , inner , ret , out , allowsFieldFlow , apa )
1519+ or
1520+ flowOutOfCallApaNotCallContextReduced ( call , inner , ret , out , allowsFieldFlow , apa ,
1521+ innercc )
1522+ )
1523+ |
1524+ outercc = getCallContextReturn ( inner , call ) and
14201525 if allowsFieldFlow = false then ap instanceof ApNil else any ( )
14211526 )
14221527 }
@@ -1518,7 +1623,7 @@ module MakeImpl<InputSig Lang> {
15181623 DataFlowCall call , ArgNodeEx arg , ParamNodeEx p , boolean allowsFieldFlow , Ap argAp , Ap ap
15191624 ) {
15201625 exists ( ApApprox argApa , Typ argT |
1521- flowIntoCallApa ( call , pragma [ only_bind_into ] ( arg ) , pragma [ only_bind_into ] ( p ) ,
1626+ flowIntoCallApa ( call , _ , pragma [ only_bind_into ] ( arg ) , pragma [ only_bind_into ] ( p ) ,
15221627 allowsFieldFlow , argApa ) and
15231628 fwdFlow ( arg , _, _, _, _, _, pragma [ only_bind_into ] ( argT ) , pragma [ only_bind_into ] ( argAp ) ,
15241629 argApa ) and
@@ -1529,24 +1634,23 @@ module MakeImpl<InputSig Lang> {
15291634 }
15301635
15311636 pragma [ nomagic]
1532- private predicate flowIntoCallAp (
1533- DataFlowCall call , ArgNodeEx arg , ParamNodeEx p , boolean allowsFieldFlow , Ap ap
1534- ) {
1535- exists ( ApApprox apa |
1536- flowIntoCallApa ( call , arg , p , allowsFieldFlow , apa ) and
1537- fwdFlow ( arg , _, _, _, _, _, _, ap , apa )
1637+ private predicate flowIntoCallAp ( DataFlowCall call , ArgNodeEx arg , ParamNodeEx p , Ap ap ) {
1638+ exists ( ApApprox apa , boolean allowsFieldFlow |
1639+ flowIntoCallApa ( call , _, arg , p , allowsFieldFlow , apa ) and
1640+ fwdFlow ( arg , _, _, _, _, _, _, ap , apa ) and
1641+ if allowsFieldFlow = false then ap instanceof ApNil else any ( )
15381642 )
15391643 }
15401644
15411645 pragma [ nomagic]
15421646 private predicate flowOutOfCallAp (
1543- DataFlowCall call , RetNodeEx ret , ReturnPosition pos , NodeEx out , boolean allowsFieldFlow ,
1544- Ap ap
1647+ DataFlowCall call , RetNodeEx ret , ReturnPosition pos , NodeEx out , Ap ap
15451648 ) {
1546- exists ( ApApprox apa |
1547- flowOutOfCallApa ( call , ret , _, out , allowsFieldFlow , apa ) and
1649+ exists ( ApApprox apa , boolean allowsFieldFlow |
1650+ flowOutOfCallApa ( call , _ , ret , _, out , allowsFieldFlow , apa ) and
15481651 fwdFlow ( ret , _, _, _, _, _, _, ap , apa ) and
1549- pos = ret .getReturnPosition ( )
1652+ pos = ret .getReturnPosition ( ) and
1653+ if allowsFieldFlow = false then ap instanceof ApNil else any ( )
15501654 )
15511655 }
15521656
@@ -1627,10 +1731,9 @@ module MakeImpl<InputSig Lang> {
16271731 )
16281732 or
16291733 // flow into a callable
1630- exists ( ParamNodeEx p , boolean allowsFieldFlow |
1734+ exists ( ParamNodeEx p |
16311735 revFlow ( p , state , TReturnCtxNone ( ) , returnAp , ap ) and
1632- flowIntoCallAp ( _, node , p , allowsFieldFlow , ap ) and
1633- ( if allowsFieldFlow = false then ap instanceof ApNil else any ( ) ) and
1736+ flowIntoCallAp ( _, node , p , ap ) and
16341737 returnCtx = TReturnCtxNone ( )
16351738 )
16361739 or
@@ -1680,10 +1783,9 @@ module MakeImpl<InputSig Lang> {
16801783 DataFlowCall call , RetNodeEx ret , ReturnPosition pos , FlowState state ,
16811784 ReturnCtx returnCtx , ApOption returnAp , Ap ap
16821785 ) {
1683- exists ( NodeEx out , boolean allowsFieldFlow |
1786+ exists ( NodeEx out |
16841787 revFlow ( out , state , returnCtx , returnAp , ap ) and
1685- flowOutOfCallAp ( call , ret , pos , out , allowsFieldFlow , ap ) and
1686- if allowsFieldFlow = false then ap instanceof ApNil else any ( )
1788+ flowOutOfCallAp ( call , ret , pos , out , ap )
16871789 )
16881790 }
16891791
@@ -1872,11 +1974,22 @@ module MakeImpl<InputSig Lang> {
18721974 bindingset [ node, cc]
18731975 LocalCc getLocalCc ( NodeEx node , Cc cc ) { any ( ) }
18741976
1875- bindingset [ call, c, outercc]
1876- CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c , Cc outercc ) { any ( ) }
1977+ DataFlowCallable viableImplCallContextReduced ( DataFlowCall call , CcCall ctx ) { none ( ) }
1978+
1979+ bindingset [ call, ctx]
1980+ predicate viableImplNotCallContextReduced ( DataFlowCall call , Cc ctx ) { any ( ) }
1981+
1982+ bindingset [ call, c]
1983+ CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c ) { any ( ) }
18771984
1878- bindingset [ call, c, innercc]
1879- CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call , Cc innercc ) { any ( ) }
1985+ DataFlowCallable viableImplCallContextReducedReverse ( DataFlowCall call , CcNoCall ctx ) {
1986+ none ( )
1987+ }
1988+
1989+ predicate viableImplNotCallContextReducedReverse ( CcNoCall ctx ) { any ( ) }
1990+
1991+ bindingset [ call, c]
1992+ CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call ) { any ( ) }
18801993 }
18811994
18821995 private module Level1CallContext {
@@ -1899,9 +2012,17 @@ module MakeImpl<InputSig Lang> {
18992012 bindingset [ node, cc]
19002013 LocalCc getLocalCc ( NodeEx node , Cc cc ) { any ( ) }
19012014
1902- bindingset [ call, c, outercc]
1903- CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c , Cc outercc ) {
1904- checkCallContextCall ( outercc , call , c ) and
2015+ DataFlowCallable viableImplCallContextReduced ( DataFlowCall call , CcCall ctx ) {
2016+ result = prunedViableImplInCallContext ( call , ctx )
2017+ }
2018+
2019+ bindingset [ call, ctx]
2020+ predicate viableImplNotCallContextReduced ( DataFlowCall call , Cc ctx ) {
2021+ noPrunedViableImplInCallContext ( call , ctx )
2022+ }
2023+
2024+ bindingset [ call, c]
2025+ CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c ) {
19052026 if recordDataFlowCallSiteDispatch ( call , c )
19062027 then result = TSpecificCall ( call )
19072028 else result = TSomeCall ( )
@@ -1918,18 +2039,33 @@ module MakeImpl<InputSig Lang> {
19182039 node .getEnclosingCallable ( ) )
19192040 }
19202041
1921- bindingset [ call, c, outercc]
1922- CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c , Cc outercc ) {
1923- checkCallContextCall ( outercc , call , c ) and
2042+ DataFlowCallable viableImplCallContextReduced ( DataFlowCall call , CcCall ctx ) {
2043+ result = prunedViableImplInCallContext ( call , ctx )
2044+ }
2045+
2046+ bindingset [ call, ctx]
2047+ predicate viableImplNotCallContextReduced ( DataFlowCall call , Cc ctx ) {
2048+ noPrunedViableImplInCallContext ( call , ctx )
2049+ }
2050+
2051+ bindingset [ call, c]
2052+ CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c ) {
19242053 if recordDataFlowCallSite ( call , c )
19252054 then result = TSpecificCall ( call )
19262055 else result = TSomeCall ( )
19272056 }
19282057 }
19292058
1930- bindingset [ call, c, innercc]
1931- CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call , Cc innercc ) {
1932- checkCallContextReturn ( innercc , c , call ) and
2059+ DataFlowCallable viableImplCallContextReducedReverse ( DataFlowCall call , CcNoCall ctx ) {
2060+ call = prunedViableImplInCallContextReverse ( result , ctx )
2061+ }
2062+
2063+ predicate viableImplNotCallContextReducedReverse ( CcNoCall ctx ) {
2064+ ctx instanceof CallContextAny
2065+ }
2066+
2067+ bindingset [ call, c]
2068+ CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call ) {
19332069 if reducedViableImplInReturn ( c , call ) then result = TReturn ( c , call ) else result = ccNone ( )
19342070 }
19352071 }
0 commit comments