@@ -123,6 +123,19 @@ module Node {
123
123
override Location getLocation ( ) { none ( ) }
124
124
}
125
125
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
+
126
139
/**
127
140
* A node in the data flow graph that corresponds to an expression in the
128
141
* AST.
@@ -131,39 +144,34 @@ module Node {
131
144
* to multiple `ExprNode`s, just like it may correspond to multiple
132
145
* `ControlFlow::Node`s.
133
146
*/
134
- class ExprNode extends Node , TExprNode {
135
- ExprCfgNode n ;
147
+ class ExprNode extends AstCfgFlowNode , TExprNode {
148
+ override ExprCfgNode n ;
136
149
137
150
ExprNode ( ) { this = TExprNode ( n ) }
138
151
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
+ }
142
154
143
- override string toString ( ) { result = n .getExpr ( ) .toString ( ) }
155
+ final class PatNode extends AstCfgFlowNode , TPatNode {
156
+ override PatCfgNode n ;
144
157
145
- override Expr asExpr ( ) { result = n . getExpr ( ) }
158
+ PatNode ( ) { this = TPatNode ( n ) }
146
159
147
- override CfgNode getCfgNode ( ) { result = n }
160
+ /** Gets the Pat in the AST that this node corresponds to. */
161
+ Pat getPat ( ) { result = n .getPat ( ) }
148
162
}
149
163
150
164
/**
151
165
* The value of a parameter at function entry, viewed as a node in a data
152
166
* flow graph.
153
167
*/
154
- final class ParameterNode extends Node , TParameterNode {
155
- ParamCfgNode parameter ;
168
+ final class ParameterNode extends AstCfgFlowNode , TParameterNode {
169
+ override ParamCfgNode n ;
156
170
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 ) }
164
172
165
173
/** Gets the parameter in the AST that this node corresponds to. */
166
- Param getParameter ( ) { result = parameter .getParam ( ) }
174
+ Param getParameter ( ) { result = n .getParam ( ) }
167
175
}
168
176
169
177
final class ArgumentNode = NaNode ;
@@ -281,6 +289,11 @@ module LocalFlow {
281
289
pragma [ nomagic]
282
290
predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
283
291
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
+ )
284
297
}
285
298
}
286
299
@@ -485,6 +498,7 @@ private module Cached {
485
498
newtype TNode =
486
499
TExprNode ( ExprCfgNode n ) or
487
500
TParameterNode ( ParamCfgNode p ) or
501
+ TPatNode ( PatCfgNode p ) or
488
502
TSsaNode ( SsaImpl:: DataFlowIntegration:: SsaNode node )
489
503
490
504
cached
0 commit comments