@@ -7,7 +7,9 @@ private import codeql.util.Unit
7
7
private import codeql.dataflow.DataFlow
8
8
private import codeql.dataflow.internal.DataFlowImpl
9
9
private import rust
10
+ private import SsaImpl as SsaImpl
10
11
private import codeql.rust.controlflow.ControlFlowGraph
12
+ private import codeql.rust.controlflow.CfgNodes
11
13
private import codeql.rust.dataflow.Ssa
12
14
13
15
module Node {
@@ -52,18 +54,43 @@ module Node {
52
54
override Location getLocation ( ) { none ( ) }
53
55
}
54
56
57
+ /**
58
+ * A node in the data flow graph that corresponds to an expression in the
59
+ * AST.
60
+ *
61
+ * Note that because of control-flow splitting, one `Expr` may correspond
62
+ * to multiple `ExprNode`s, just like it may correspond to multiple
63
+ * `ControlFlow::Node`s.
64
+ */
65
+ final class ExprNode extends Node , TExprNode {
66
+ ExprCfgNode n ;
67
+
68
+ ExprNode ( ) { this = TExprNode ( n ) }
69
+
70
+ override Location getLocation ( ) { result = n .getExpr ( ) .getLocation ( ) }
71
+
72
+ override string toString ( ) { result = n .getExpr ( ) .toString ( ) }
73
+
74
+ override Expr asExpr ( ) { result = n .getExpr ( ) }
75
+
76
+ override CfgNode getCfgNode ( ) { result = n }
77
+ }
78
+
55
79
/**
56
80
* The value of a parameter at function entry, viewed as a node in a data
57
81
* flow graph.
58
82
*/
59
- final class ParameterNode extends Node {
60
- Param param ;
83
+ final class ParameterNode extends Node , TParameterNode {
84
+ Param parameter ;
85
+
86
+ ParameterNode ( ) { this = TParameterNode ( parameter ) }
61
87
62
- ParameterNode ( ) { this = TSourceParameterNode ( param ) }
88
+ override Location getLocation ( ) { result = parameter . getLocation ( ) }
63
89
64
- override Location getLocation ( ) { result = param . getLocation ( ) }
90
+ override string toString ( ) { result = parameter . toString ( ) }
65
91
66
- override string toString ( ) { result = param .toString ( ) }
92
+ /** Gets the parameter in the AST that this node corresponds to. */
93
+ Param getParameter ( ) { result = parameter }
67
94
}
68
95
69
96
final class ArgumentNode = NaNode ;
@@ -93,6 +120,32 @@ module Node {
93
120
final class CastNode = NaNode ;
94
121
}
95
122
123
+ final class Node = Node:: Node ;
124
+
125
+ /** Provides logic related to SSA. */
126
+ module SsaFlow {
127
+ private module Impl = SsaImpl:: DataFlowIntegration;
128
+
129
+ private Node:: ParameterNode toParameterNode ( Param p ) { result = TParameterNode ( p ) }
130
+
131
+ /** Converts a control flow node into an SSA control flow node. */
132
+ Impl:: Node asNode ( Node n ) {
133
+ n = TSsaNode ( result )
134
+ or
135
+ result .( Impl:: ExprNode ) .getExpr ( ) = n .( Node:: ExprNode ) .getCfgNode ( )
136
+ or
137
+ n = toParameterNode ( result .( Impl:: ParameterNode ) .getParameter ( ) )
138
+ }
139
+
140
+ predicate localFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo , boolean isUseStep ) {
141
+ Impl:: localFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) , isUseStep )
142
+ }
143
+
144
+ predicate localMustFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo ) {
145
+ Impl:: localMustFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) )
146
+ }
147
+ }
148
+
96
149
module RustDataFlow implements InputSig< Location > {
97
150
/**
98
151
* An element, viewed as a node in a data flow graph. Either an expression
@@ -122,10 +175,10 @@ module RustDataFlow implements InputSig<Location> {
122
175
123
176
predicate nodeIsHidden ( Node node ) { none ( ) }
124
177
125
- class DataFlowExpr = Void ;
178
+ class DataFlowExpr = ExprCfgNode ;
126
179
127
180
/** Gets the node corresponding to `e`. */
128
- Node exprNode ( DataFlowExpr e ) { none ( ) }
181
+ Node exprNode ( DataFlowExpr e ) { result . getCfgNode ( ) = e }
129
182
130
183
final class DataFlowCall extends TNormalCall {
131
184
private CallExpr c ;
@@ -191,7 +244,7 @@ module RustDataFlow implements InputSig<Location> {
191
244
* Holds if there is a simple local flow step from `node1` to `node2`. These
192
245
* are the value-preserving intra-callable flow steps.
193
246
*/
194
- predicate simpleLocalFlowStep ( Node node1 , Node node2 , string model ) { none ( ) }
247
+ predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo , string model ) { none ( ) }
195
248
196
249
/**
197
250
* Holds if data can flow from `node1` to `node2` through a non-local step
@@ -256,7 +309,9 @@ module RustDataFlow implements InputSig<Location> {
256
309
* `node2` must be visited along a flow path, then any type known for `node2`
257
310
* must also apply to `node1`.
258
311
*/
259
- predicate localMustFlowStep ( Node node1 , Node node2 ) { none ( ) }
312
+ predicate localMustFlowStep ( Node node1 , Node node2 ) {
313
+ SsaFlow:: localMustFlowStep ( _, node1 , node2 )
314
+ }
260
315
261
316
class LambdaCallKind = Void ;
262
317
@@ -267,7 +322,7 @@ module RustDataFlow implements InputSig<Location> {
267
322
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
268
323
predicate lambdaCall ( DataFlowCall call , LambdaCallKind kind , Node receiver ) { none ( ) }
269
324
270
- /** Extra data- flow steps needed for lambda flow analysis. */
325
+ /** Extra data flow steps needed for lambda flow analysis. */
271
326
predicate additionalLambdaFlowStep ( Node nodeFrom , Node nodeTo , boolean preservesValue ) { none ( ) }
272
327
273
328
predicate knownSourceModel ( Node source , string model ) { none ( ) }
@@ -286,8 +341,9 @@ cached
286
341
private module Cached {
287
342
cached
288
343
newtype TNode =
289
- TExprNode ( CfgNode n , Expr e ) { n .getAstNode ( ) = e } or
290
- TSourceParameterNode ( Param param )
344
+ TExprNode ( ExprCfgNode n ) or
345
+ TParameterNode ( Param p ) or
346
+ TSsaNode ( SsaImpl:: DataFlowIntegration:: SsaNode node )
291
347
292
348
cached
293
349
newtype TDataFlowCall = TNormalCall ( CallExpr c )
@@ -302,7 +358,9 @@ private module Cached {
302
358
303
359
/** This is the local flow predicate that is exposed. */
304
360
cached
305
- predicate localFlowStepImpl ( Node:: Node nodeFrom , Node:: Node nodeTo ) { none ( ) }
361
+ predicate localFlowStepImpl ( Node:: Node nodeFrom , Node:: Node nodeTo ) {
362
+ SsaFlow:: localFlowStep ( _, nodeFrom , nodeTo , _)
363
+ }
306
364
}
307
365
308
366
import Cached
0 commit comments