@@ -111,6 +111,19 @@ module Node {
111
111
override Location getLocation ( ) { none ( ) }
112
112
}
113
113
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
+
114
127
/**
115
128
* A node in the data flow graph that corresponds to an expression in the
116
129
* AST.
@@ -119,39 +132,34 @@ module Node {
119
132
* to multiple `ExprNode`s, just like it may correspond to multiple
120
133
* `ControlFlow::Node`s.
121
134
*/
122
- class ExprNode extends Node , TExprNode {
123
- ExprCfgNode n ;
135
+ class ExprNode extends AstCfgFlowNode , TExprNode {
136
+ override ExprCfgNode n ;
124
137
125
138
ExprNode ( ) { this = TExprNode ( n ) }
126
139
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
+ }
130
142
131
- override string toString ( ) { result = n .getExpr ( ) .toString ( ) }
143
+ final class PatNode extends AstCfgFlowNode , TPatNode {
144
+ override PatCfgNode n ;
132
145
133
- override Expr asExpr ( ) { result = n . getExpr ( ) }
146
+ PatNode ( ) { this = TPatNode ( n ) }
134
147
135
- override CfgNode getCfgNode ( ) { result = n }
148
+ /** Gets the Pat in the AST that this node corresponds to. */
149
+ Pat getPat ( ) { result = n .getPat ( ) }
136
150
}
137
151
138
152
/**
139
153
* The value of a parameter at function entry, viewed as a node in a data
140
154
* flow graph.
141
155
*/
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 ;
146
158
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 ) }
152
160
153
161
/** Gets the parameter in the AST that this node corresponds to. */
154
- Param getParameter ( ) { result = parameter .getParam ( ) }
162
+ Param getParameter ( ) { result = n .getParam ( ) }
155
163
}
156
164
157
165
final class ArgumentNode = NaNode ;
@@ -269,6 +277,11 @@ module LocalFlow {
269
277
pragma [ nomagic]
270
278
predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
271
279
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
+ )
272
285
}
273
286
}
274
287
@@ -481,6 +494,7 @@ private module Cached {
481
494
newtype TNode =
482
495
TExprNode ( ExprCfgNode n ) or
483
496
TParameterNode ( ParamCfgNode p ) or
497
+ TPatNode ( PatCfgNode p ) or
484
498
TSsaNode ( SsaImpl:: DataFlowIntegration:: SsaNode node )
485
499
486
500
cached
0 commit comments