@@ -188,11 +188,7 @@ module DataFlow {
188188 lvalueFlowStep ( result , this ) and
189189 not lvalueDefaultFlowStep ( _, this )
190190 or
191- // Use of variable -> definition of variable
192- exists ( SsaVariable var |
193- this = valueNode ( var .getAUse ( ) ) and
194- result = TSsaDefNode ( var )
195- )
191+ immediateFlowStep ( result , this )
196192 or
197193 // Refinement of variable -> original definition of variable
198194 exists ( SsaRefinementNode refinement |
@@ -1299,6 +1295,44 @@ module DataFlow {
12991295 )
13001296 }
13011297
1298+ /**
1299+ * Flow steps shared between `getImmediatePredecessor` and `localFlowStep`.
1300+ *
1301+ * Inlining is forced because the two relations are indexed differently.
1302+ */
1303+ pragma [ inline]
1304+ private predicate immediateFlowStep ( Node pred , Node succ ) {
1305+ exists ( SsaVariable v |
1306+ pred = TSsaDefNode ( v .getDefinition ( ) ) and
1307+ succ = valueNode ( v .getAUse ( ) )
1308+ )
1309+ or
1310+ exists ( Expr predExpr , Expr succExpr |
1311+ pred = valueNode ( predExpr ) and succ = valueNode ( succExpr )
1312+ |
1313+ predExpr = succExpr .( ParExpr ) .getExpression ( )
1314+ or
1315+ predExpr = succExpr .( SeqExpr ) .getLastOperand ( )
1316+ or
1317+ predExpr = succExpr .( AssignExpr ) .getRhs ( )
1318+ or
1319+ predExpr = succExpr .( TypeAssertion ) .getExpression ( )
1320+ or
1321+ predExpr = succExpr .( NonNullAssertion ) .getExpression ( )
1322+ or
1323+ predExpr = succExpr .( ExpressionWithTypeArguments ) .getExpression ( )
1324+ )
1325+ or
1326+ // flow from 'this' parameter into 'this' expressions
1327+ exists ( ThisExpr thiz |
1328+ pred = TThisNode ( thiz .getBindingContainer ( ) ) and
1329+ succ = valueNode ( thiz )
1330+ )
1331+ or
1332+ // `f.call(...)` and `f.apply(...)` evaluate to the result of the reflective call they perform
1333+ pred = TReflectiveCallNode ( succ .asExpr ( ) , _)
1334+ }
1335+
13021336 /**
13031337 * Holds if data can flow from `pred` to `succ` in one local step.
13041338 */
@@ -1309,6 +1343,8 @@ module DataFlow {
13091343 or
13101344 lvalueDefaultFlowStep ( pred , succ )
13111345 or
1346+ immediateFlowStep ( pred , succ )
1347+ or
13121348 // Flow through implicit SSA nodes
13131349 exists ( SsaImplicitDefinition ssa | succ = TSsaDefNode ( ssa ) |
13141350 // from any explicit definition or implicit init of a captured variable into
@@ -1326,45 +1362,18 @@ module DataFlow {
13261362 pred = TSsaDefNode ( ssa .( SsaPseudoDefinition ) .getAnInput ( ) .getDefinition ( ) )
13271363 )
13281364 or
1329- // flow out of local variables
1330- exists ( SsaVariable v |
1331- pred = TSsaDefNode ( v .getDefinition ( ) ) and
1332- succ = valueNode ( v .getAUse ( ) )
1333- )
1334- or
13351365 exists ( Expr predExpr , Expr succExpr |
13361366 pred = valueNode ( predExpr ) and succ = valueNode ( succExpr )
13371367 |
1338- predExpr = succExpr .( ParExpr ) .getExpression ( )
1339- or
1340- predExpr = succExpr .( SeqExpr ) .getLastOperand ( )
1341- or
13421368 predExpr = succExpr .( LogicalBinaryExpr ) .getAnOperand ( )
13431369 or
1344- predExpr = succExpr .( AssignExpr ) .getRhs ( )
1345- or
13461370 predExpr = succExpr .( ConditionalExpr ) .getABranch ( )
13471371 or
1348- predExpr = succExpr .( TypeAssertion ) .getExpression ( )
1349- or
1350- predExpr = succExpr .( NonNullAssertion ) .getExpression ( )
1351- or
1352- predExpr = succExpr .( ExpressionWithTypeArguments ) .getExpression ( )
1353- or
13541372 exists ( Function f |
13551373 predExpr = f .getAReturnedExpr ( ) and
13561374 localCall ( succExpr , f )
13571375 )
13581376 )
1359- or
1360- // flow from 'this' parameter into 'this' expressions
1361- exists ( ThisExpr thiz |
1362- pred = TThisNode ( thiz .getBindingContainer ( ) ) and
1363- succ = valueNode ( thiz )
1364- )
1365- or
1366- // `f.call(...)` and `f.apply(...)` evaluate to the result of the reflective call they perform
1367- pred = TReflectiveCallNode ( succ .asExpr ( ) , _)
13681377 }
13691378
13701379 /**
0 commit comments