@@ -628,6 +628,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
628628 override string toString ( ) {
629629 exists ( DataFlowCall call | this = TReturn ( _, call ) | result = "CcReturn(" + call + ")" )
630630 }
631+
632+ predicate isReturn ( DataFlowCallable c , DataFlowCall call ) { this = TReturn ( c , call ) }
631633 }
632634
633635 pragma [ nomagic]
@@ -676,8 +678,12 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
676678 cc = ccSomeCall ( )
677679 }
678680
681+ class CcAny = CallContextAny ;
682+
679683 class CcNoCall = CallContextNoCall ;
680684
685+ class CcReturn = CallContextReturn ;
686+
681687 Cc ccNone ( ) { result instanceof CallContextAny }
682688
683689 CcCall ccSomeCall ( ) { result instanceof CallContextSomeCall }
@@ -1348,8 +1354,12 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
13481354 * If a read step was taken, then `read` captures the `Content`, the
13491355 * container type, and the content type.
13501356 */
1351- predicate parameterValueFlow ( ParamNode p , Node node , ReadStepTypesOption read , string model ) {
1352- parameterValueFlow0 ( p , node , read , model ) and
1357+ predicate parameterValueFlow (
1358+ ParamNode p , Node node , ReadStepTypesOption read , string model ,
1359+ CachedCallContextSensitivity:: CcNoCall ctx
1360+ ) {
1361+ parameterValueFlow0 ( p , node , read , model , ctx ) and
1362+ Cand:: cand ( p , node ) and
13531363 if node instanceof CastingNode
13541364 then
13551365 // normal flow through
@@ -1369,67 +1379,115 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
13691379
13701380 pragma [ nomagic]
13711381 private predicate parameterValueFlow0 (
1372- ParamNode p , Node node , ReadStepTypesOption read , string model
1382+ ParamNode p , Node node , ReadStepTypesOption read , string model ,
1383+ CachedCallContextSensitivity:: CcNoCall ctx
13731384 ) {
13741385 p = node and
13751386 Cand:: cand ( p , _) and
13761387 read = TReadStepTypesNone ( ) and
1377- model = ""
1388+ model = "" and
1389+ ctx instanceof CachedCallContextSensitivity:: CcAny
13781390 or
13791391 // local flow
13801392 exists ( Node mid , string model1 , string model2 |
1381- parameterValueFlow ( p , mid , read , model1 ) and
1393+ parameterValueFlow ( p , mid , read , model1 , ctx ) and
13821394 simpleLocalFlowStep ( mid , node , model2 ) and
13831395 validParameterAliasStep ( mid , node ) and
13841396 model = mergeModels ( model1 , model2 )
13851397 )
13861398 or
13871399 // read
13881400 exists ( Node mid |
1389- parameterValueFlow ( p , mid , TReadStepTypesNone ( ) , model ) and
1401+ parameterValueFlow ( p , mid , TReadStepTypesNone ( ) , model , ctx ) and
13901402 readStepWithTypes ( mid , read .getContainerType ( ) , read .getContent ( ) , node ,
13911403 read .getContentType ( ) ) and
13921404 Cand:: parameterValueFlowReturnCand ( p , _, true ) and
13931405 compatibleTypesFilter ( getNodeDataFlowType ( p ) , read .getContainerType ( ) )
13941406 )
13951407 or
1396- parameterValueFlow0_0 ( TReadStepTypesNone ( ) , p , node , read , model )
1408+ parameterValueFlow0_0 ( TReadStepTypesNone ( ) , p , node , read , model , ctx )
13971409 }
13981410
13991411 pragma [ nomagic]
14001412 private predicate parameterValueFlow0_0 (
14011413 ReadStepTypesOption mustBeNone , ParamNode p , Node node , ReadStepTypesOption read ,
1402- string model
1414+ string model , CachedCallContextSensitivity :: CcNoCall ctx
14031415 ) {
1404- // flow through: no prior read
1405- exists ( ArgNode arg , string model1 , string model2 |
1406- parameterValueFlowArg ( p , arg , mustBeNone , model1 ) and
1407- argumentValueFlowsThrough ( arg , read , node , model2 ) and
1408- model = mergeModels ( model1 , model2 )
1409- )
1410- or
1411- // flow through: no read inside method
1412- exists ( ArgNode arg , string model1 , string model2 |
1413- parameterValueFlowArg ( p , arg , read , model1 ) and
1414- argumentValueFlowsThrough ( arg , mustBeNone , node , model2 ) and
1415- model = mergeModels ( model1 , model2 )
1416+ exists (
1417+ DataFlowCall call , DataFlowCallable callable , ArgNode arg , string model1 , string model2 ,
1418+ CachedCallContextSensitivity:: CcNoCall prevCtx
1419+ |
1420+ model = mergeModels ( model1 , model2 ) and
1421+ (
1422+ ctx .( CachedCallContextSensitivity:: CcReturn ) .isReturn ( callable , call ) and
1423+ (
1424+ CachedCallContextSensitivity:: viableImplNotCallContextReducedReverse ( prevCtx )
1425+ or
1426+ // check that `prevCtx` is compatible with `ctx` for at least some outer call
1427+ exists ( DataFlowCall someOuterCall |
1428+ someOuterCall =
1429+ CachedCallContextSensitivity:: viableImplCallContextReducedReverse ( callable ,
1430+ prevCtx ) and
1431+ someOuterCall =
1432+ CachedCallContextSensitivity:: viableImplCallContextReducedReverse ( callable , ctx )
1433+ )
1434+ )
1435+ or
1436+ not exists ( CachedCallContextSensitivity:: CcReturn ret | ret .isReturn ( callable , call ) ) and
1437+ ctx = prevCtx
1438+ )
1439+ |
1440+ // flow through: no prior read
1441+ parameterValueFlowArg ( p , arg , mustBeNone , model1 , prevCtx ) and
1442+ argumentValueFlowsThrough ( call , callable , arg , read , node , model2 )
1443+ or
1444+ // flow through: no read inside method
1445+ parameterValueFlowArg ( p , arg , read , model1 , prevCtx ) and
1446+ argumentValueFlowsThrough ( call , callable , arg , mustBeNone , node , model2 )
14161447 )
14171448 }
14181449
14191450 pragma [ nomagic]
14201451 private predicate parameterValueFlowArg (
1421- ParamNode p , ArgNode arg , ReadStepTypesOption read , string model
1452+ ParamNode p , ArgNode arg , ReadStepTypesOption read , string model ,
1453+ CachedCallContextSensitivity:: CcNoCall ctx
14221454 ) {
1423- parameterValueFlow ( p , arg , read , model ) and
1455+ parameterValueFlow ( p , arg , read , model , ctx ) and
14241456 Cand:: argumentValueFlowsThroughCand ( arg , _, _)
14251457 }
14261458
14271459 pragma [ nomagic]
14281460 private predicate argumentValueFlowsThrough0 (
1429- DataFlowCall call , ArgNode arg , ReturnKind kind , ReadStepTypesOption read , string model
1461+ DataFlowCall call , DataFlowCallable callable , ArgNode arg , ReturnKind kind ,
1462+ ReadStepTypesOption read , string model
14301463 ) {
1431- exists ( ParamNode param | viableParamArg ( call , param , arg ) |
1432- parameterValueFlowReturn ( param , kind , read , model )
1464+ exists ( ParamNode param , CachedCallContextSensitivity:: CcNoCall ctx |
1465+ viableParamArg ( call , param , arg ) and
1466+ parameterValueFlowReturn ( param , kind , read , model , ctx ) and
1467+ callable = nodeGetEnclosingCallable ( param )
1468+ |
1469+ CachedCallContextSensitivity:: viableImplNotCallContextReducedReverse ( ctx )
1470+ or
1471+ call = CachedCallContextSensitivity:: viableImplCallContextReducedReverse ( callable , ctx )
1472+ )
1473+ }
1474+
1475+ pragma [ nomagic]
1476+ private predicate argumentValueFlowsThrough (
1477+ DataFlowCall call , DataFlowCallable callable , ArgNode arg , ReadStepTypesOption read ,
1478+ Node out , string model
1479+ ) {
1480+ exists ( ReturnKind kind |
1481+ argumentValueFlowsThrough0 ( call , callable , arg , kind , read , model ) and
1482+ out = getAnOutNode ( call , kind )
1483+ |
1484+ // normal flow through
1485+ read = TReadStepTypesNone ( ) and
1486+ compatibleTypesFilter ( getNodeDataFlowType ( arg ) , getNodeDataFlowType ( out ) )
1487+ or
1488+ // getter
1489+ compatibleTypesFilter ( getNodeDataFlowType ( arg ) , read .getContainerType ( ) ) and
1490+ compatibleTypesFilter ( read .getContentType ( ) , getNodeDataFlowType ( out ) )
14331491 )
14341492 }
14351493
@@ -1445,18 +1503,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
14451503 predicate argumentValueFlowsThrough (
14461504 ArgNode arg , ReadStepTypesOption read , Node out , string model
14471505 ) {
1448- exists ( DataFlowCall call , ReturnKind kind |
1449- argumentValueFlowsThrough0 ( call , arg , kind , read , model ) and
1450- out = getAnOutNode ( call , kind )
1451- |
1452- // normal flow through
1453- read = TReadStepTypesNone ( ) and
1454- compatibleTypesFilter ( getNodeDataFlowType ( arg ) , getNodeDataFlowType ( out ) )
1455- or
1456- // getter
1457- compatibleTypesFilter ( getNodeDataFlowType ( arg ) , read .getContainerType ( ) ) and
1458- compatibleTypesFilter ( read .getContentType ( ) , getNodeDataFlowType ( out ) )
1459- )
1506+ argumentValueFlowsThrough ( _, _, arg , read , out , model )
14601507 }
14611508
14621509 /**
@@ -1479,10 +1526,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
14791526 * container type, and the content type.
14801527 */
14811528 private predicate parameterValueFlowReturn (
1482- ParamNode p , ReturnKind kind , ReadStepTypesOption read , string model
1529+ ParamNode p , ReturnKind kind , ReadStepTypesOption read , string model ,
1530+ CachedCallContextSensitivity:: CcNoCall ctx
14831531 ) {
14841532 exists ( ReturnNode ret |
1485- parameterValueFlow ( p , ret , read , model ) and
1533+ parameterValueFlow ( p , ret , read , model , ctx ) and
14861534 kind = ret .getKind ( )
14871535 )
14881536 }
@@ -1498,7 +1546,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
14981546 * node `n`, in the same callable, using only value-preserving steps.
14991547 */
15001548 private predicate parameterValueFlowsToPreUpdate ( ParamNode p , PostUpdateNode n ) {
1501- parameterValueFlow ( p , n .getPreUpdateNode ( ) , TReadStepTypesNone ( ) , _)
1549+ parameterValueFlow ( p , n .getPreUpdateNode ( ) , TReadStepTypesNone ( ) , _, _ )
15021550 }
15031551
15041552 cached
0 commit comments