@@ -123,6 +123,19 @@ module Node {
123123 override Location getLocation ( ) { none ( ) }
124124 }
125125
126+ /** A data flow node that corresponds to a CFG node for an AST node. */
127+ abstract private class AstCfgFlowNode extends Node {
128+ AstCfgNode n ;
129+
130+ override CfgNode getCfgNode ( ) { result = n }
131+
132+ override CfgScope getCfgScope ( ) { result = n .getAstNode ( ) .getEnclosingCallable ( ) }
133+
134+ override Location getLocation ( ) { result = n .getAstNode ( ) .getLocation ( ) }
135+
136+ override string toString ( ) { result = n .getAstNode ( ) .toString ( ) }
137+ }
138+
126139 /**
127140 * A node in the data flow graph that corresponds to an expression in the
128141 * AST.
@@ -131,39 +144,34 @@ module Node {
131144 * to multiple `ExprNode`s, just like it may correspond to multiple
132145 * `ControlFlow::Node`s.
133146 */
134- class ExprNode extends Node , TExprNode {
135- ExprCfgNode n ;
147+ class ExprNode extends AstCfgFlowNode , TExprNode {
148+ override ExprCfgNode n ;
136149
137150 ExprNode ( ) { this = TExprNode ( n ) }
138151
139- override CfgScope getCfgScope ( ) { result = this .asExpr ( ) .getEnclosingCallable ( ) }
140-
141- override Location getLocation ( ) { result = n .getExpr ( ) .getLocation ( ) }
152+ override Expr asExpr ( ) { result = n .getExpr ( ) }
153+ }
142154
143- override string toString ( ) { result = n .getExpr ( ) .toString ( ) }
155+ final class PatNode extends AstCfgFlowNode , TPatNode {
156+ override PatCfgNode n ;
144157
145- override Expr asExpr ( ) { result = n . getExpr ( ) }
158+ PatNode ( ) { this = TPatNode ( n ) }
146159
147- override CfgNode getCfgNode ( ) { result = n }
160+ /** Gets the Pat in the AST that this node corresponds to. */
161+ Pat getPat ( ) { result = n .getPat ( ) }
148162 }
149163
150164 /**
151165 * The value of a parameter at function entry, viewed as a node in a data
152166 * flow graph.
153167 */
154- final class ParameterNode extends Node , TParameterNode {
155- ParamCfgNode parameter ;
168+ final class ParameterNode extends AstCfgFlowNode , TParameterNode {
169+ override ParamCfgNode n ;
156170
157- ParameterNode ( ) { this = TParameterNode ( parameter ) }
158-
159- override CfgScope getCfgScope ( ) { result = parameter .getParam ( ) .getEnclosingCallable ( ) }
160-
161- override Location getLocation ( ) { result = parameter .getLocation ( ) }
162-
163- override string toString ( ) { result = parameter .toString ( ) }
171+ ParameterNode ( ) { this = TParameterNode ( n ) }
164172
165173 /** Gets the parameter in the AST that this node corresponds to. */
166- Param getParameter ( ) { result = parameter .getParam ( ) }
174+ Param getParameter ( ) { result = n .getParam ( ) }
167175 }
168176
169177 final class ArgumentNode = NaNode ;
@@ -281,6 +289,11 @@ module LocalFlow {
281289 pragma [ nomagic]
282290 predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
283291 nodeFrom .getCfgNode ( ) = getALastEvalNode ( nodeTo .getCfgNode ( ) )
292+ or
293+ exists ( LetStmt s |
294+ nodeFrom .getCfgNode ( ) .getAstNode ( ) = s .getInitializer ( ) and
295+ nodeTo .getCfgNode ( ) .getAstNode ( ) = s .getPat ( )
296+ )
284297 }
285298}
286299
@@ -485,6 +498,7 @@ private module Cached {
485498 newtype TNode =
486499 TExprNode ( ExprCfgNode n ) or
487500 TParameterNode ( ParamCfgNode p ) or
501+ TPatNode ( PatCfgNode p ) or
488502 TSsaNode ( SsaImpl:: DataFlowIntegration:: SsaNode node )
489503
490504 cached
0 commit comments