@@ -111,6 +111,19 @@ module Node {
111111 override Location getLocation ( ) { none ( ) }
112112 }
113113
114+ /** A data flow node that corresponds to a CFG node for an AST node. */
115+ abstract private class AstCfgFlowNode extends Node {
116+ AstCfgNode n ;
117+
118+ override CfgNode getCfgNode ( ) { result = n }
119+
120+ override CfgScope getCfgScope ( ) { result = n .getAstNode ( ) .getEnclosingCfgScope ( ) }
121+
122+ override Location getLocation ( ) { result = n .getAstNode ( ) .getLocation ( ) }
123+
124+ override string toString ( ) { result = n .getAstNode ( ) .toString ( ) }
125+ }
126+
114127 /**
115128 * A node in the data flow graph that corresponds to an expression in the
116129 * AST.
@@ -119,39 +132,34 @@ module Node {
119132 * to multiple `ExprNode`s, just like it may correspond to multiple
120133 * `ControlFlow::Node`s.
121134 */
122- class ExprNode extends Node , TExprNode {
123- ExprCfgNode n ;
135+ class ExprNode extends AstCfgFlowNode , TExprNode {
136+ override ExprCfgNode n ;
124137
125138 ExprNode ( ) { this = TExprNode ( n ) }
126139
127- override CfgScope getCfgScope ( ) { result = this .asExpr ( ) .getEnclosingCfgScope ( ) }
128-
129- override Location getLocation ( ) { result = n .getExpr ( ) .getLocation ( ) }
140+ override Expr asExpr ( ) { result = n .getExpr ( ) }
141+ }
130142
131- override string toString ( ) { result = n .getExpr ( ) .toString ( ) }
143+ final class PatNode extends AstCfgFlowNode , TPatNode {
144+ override PatCfgNode n ;
132145
133- override Expr asExpr ( ) { result = n . getExpr ( ) }
146+ PatNode ( ) { this = TPatNode ( n ) }
134147
135- override CfgNode getCfgNode ( ) { result = n }
148+ /** Gets the Pat in the AST that this node corresponds to. */
149+ Pat getPat ( ) { result = n .getPat ( ) }
136150 }
137151
138152 /**
139153 * The value of a parameter at function entry, viewed as a node in a data
140154 * flow graph.
141155 */
142- final class ParameterNode extends Node , TParameterNode {
143- ParamCfgNode parameter ;
144-
145- ParameterNode ( ) { this = TParameterNode ( parameter ) }
156+ final class ParameterNode extends AstCfgFlowNode , TParameterNode {
157+ override ParamCfgNode n ;
146158
147- override CfgScope getCfgScope ( ) { result = parameter .getParam ( ) .getEnclosingCfgScope ( ) }
148-
149- override Location getLocation ( ) { result = parameter .getLocation ( ) }
150-
151- override string toString ( ) { result = parameter .toString ( ) }
159+ ParameterNode ( ) { this = TParameterNode ( n ) }
152160
153161 /** Gets the parameter in the AST that this node corresponds to. */
154- Param getParameter ( ) { result = parameter .getParam ( ) }
162+ Param getParameter ( ) { result = n .getParam ( ) }
155163 }
156164
157165 final class ArgumentNode = NaNode ;
@@ -269,6 +277,11 @@ module LocalFlow {
269277 pragma [ nomagic]
270278 predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
271279 nodeFrom .getCfgNode ( ) = getALastEvalNode ( nodeTo .getCfgNode ( ) )
280+ or
281+ exists ( LetStmt s |
282+ nodeFrom .getCfgNode ( ) .getAstNode ( ) = s .getInitializer ( ) and
283+ nodeTo .getCfgNode ( ) .getAstNode ( ) = s .getPat ( )
284+ )
272285 }
273286}
274287
@@ -481,6 +494,7 @@ private module Cached {
481494 newtype TNode =
482495 TExprNode ( ExprCfgNode n ) or
483496 TParameterNode ( ParamCfgNode p ) or
497+ TPatNode ( PatCfgNode p ) or
484498 TSsaNode ( SsaImpl:: DataFlowIntegration:: SsaNode node )
485499
486500 cached
0 commit comments