@@ -70,6 +70,20 @@ module LocalFlow {
7070 )
7171 }
7272
73+ /** Gets the SSA definition node corresponding to the implicit `self` parameter for `m`. */
74+ private SsaDefinitionNode getSelfParameterDefNode ( MethodBase m ) {
75+ result .getDefinition ( ) .( Ssa:: SelfDefinition ) .getSourceVariable ( ) .getDeclaringScope ( ) = m
76+ }
77+
78+ /**
79+ * Holds if `nodeFrom` is a parameter node, and `nodeTo` is a corresponding SSA node.
80+ */
81+ predicate localFlowSsaParamInput ( Node nodeFrom , Node nodeTo ) {
82+ nodeTo = getParameterDefNode ( nodeFrom .( ParameterNode ) .getParameter ( ) )
83+ or
84+ nodeTo = getSelfParameterDefNode ( nodeFrom .( SelfParameterNode ) .getMethod ( ) )
85+ }
86+
7387 /**
7488 * Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo`
7589 * involving SSA definition `def`.
@@ -115,9 +129,6 @@ module LocalFlow {
115129 predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
116130 localSsaFlowStep ( nodeFrom , nodeTo )
117131 or
118- nodeFrom .( SelfParameterNode ) .getMethod ( ) = nodeTo .asExpr ( ) .getExpr ( ) .getEnclosingCallable ( ) and
119- nodeTo .asExpr ( ) .getExpr ( ) instanceof Self
120- or
121132 nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: AssignExprCfgNode ) .getRhs ( )
122133 or
123134 nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: BlockArgumentCfgNode ) .getValue ( )
@@ -236,7 +247,7 @@ private module Cached {
236247 or
237248 defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
238249 or
239- nodeTo = LocalFlow:: getParameterDefNode ( nodeFrom . ( ParameterNode ) . getParameter ( ) )
250+ LocalFlow:: localFlowSsaParamInput ( nodeFrom , nodeTo )
240251 or
241252 nodeTo .( SynthReturnNode ) .getAnInput ( ) = nodeFrom
242253 or
@@ -253,7 +264,7 @@ private module Cached {
253264 or
254265 defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
255266 or
256- nodeTo = LocalFlow:: getParameterDefNode ( nodeFrom . ( ParameterNode ) . getParameter ( ) )
267+ LocalFlow:: localFlowSsaParamInput ( nodeFrom , nodeTo )
257268 or
258269 LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo )
259270 or
@@ -275,27 +286,34 @@ private module Cached {
275286 LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo )
276287 }
277288
289+ private predicate entrySsaDefinition ( SsaDefinitionNode n ) {
290+ n = LocalFlow:: getParameterDefNode ( _)
291+ or
292+ exists ( Ssa:: Definition def | def = n .getDefinition ( ) |
293+ def instanceof Ssa:: SelfDefinition
294+ or
295+ def instanceof Ssa:: CapturedEntryDefinition
296+ )
297+ }
298+
278299 cached
279300 predicate isLocalSourceNode ( Node n ) {
280301 n instanceof ParameterNode
281302 or
282- // This case should not be needed once we have proper use-use flow
283- // for `self`. At that point, the `self`s returned by `trackInstance`
284- // in `DataFlowDispatch.qll` should refer to the post-update node,
285- // and we can remove this case.
286- n .asExpr ( ) .getExpr ( ) instanceof Self
303+ n instanceof PostUpdateNodes:: ExprPostUpdateNode
287304 or
288- // Nodes that can't be reached from another parameter or expression.
289- not localFlowStepTypeTracker + ( any ( Node e |
290- e instanceof ExprNode
305+ // Expressions that can't be reached from another entry definition or expression.
306+ not localFlowStepTypeTracker + ( any ( Node n0 |
307+ n0 instanceof ExprNode
291308 or
292- e instanceof ParameterNode
293- ) , n )
309+ entrySsaDefinition ( n0 )
310+ ) , n . ( ExprNode ) )
294311 or
295- // Ensure all parameter SSA nodes are local sources -- this is needed by type tracking.
296- // Note that when the parameter has a default value, it will be reachable from an
297- // expression (the default value) and therefore won't be caught by the rule above.
298- n = LocalFlow:: getParameterDefNode ( _)
312+ // Ensure all entry SSA definitions are local sources -- for parameters, this
313+ // is needed by type tracking. Note that when the parameter has a default value,
314+ // it will be reachable from an expression (the default value) and therefore
315+ // won't be caught by the rule above.
316+ entrySsaDefinition ( n )
299317 }
300318
301319 cached
@@ -358,6 +376,16 @@ class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode {
358376 override string toStringImpl ( ) { result = def .toString ( ) }
359377}
360378
379+ /** An SSA definition for a `self` variable. */
380+ class SsaSelfDefinitionNode extends LocalSourceNode , SsaDefinitionNode {
381+ private SelfVariable self ;
382+
383+ SsaSelfDefinitionNode ( ) { self = def .getSourceVariable ( ) }
384+
385+ /** Gets the scope in which the `self` variable is declared. */
386+ Scope getSelfScope ( ) { result = self .getDeclaringScope ( ) }
387+ }
388+
361389/**
362390 * A value returning statement, viewed as a node in a data flow graph.
363391 *
@@ -745,13 +773,6 @@ predicate jumpStep(Node pred, Node succ) {
745773 SsaImpl:: captureFlowOut ( pred .( SsaDefinitionNode ) .getDefinition ( ) ,
746774 succ .( SsaDefinitionNode ) .getDefinition ( ) )
747775 or
748- exists ( Self s , Method m |
749- s = succ .asExpr ( ) .getExpr ( ) and
750- pred .( SelfParameterNode ) .getMethod ( ) = m and
751- m = s .getEnclosingMethod ( ) and
752- m != s .getEnclosingCallable ( )
753- )
754- or
755776 succ .asExpr ( ) .getExpr ( ) .( ConstantReadAccess ) .getValue ( ) = pred .asExpr ( ) .getExpr ( )
756777}
757778
0 commit comments