@@ -7,7 +7,9 @@ private import codeql.util.Unit
77private import codeql.dataflow.DataFlow
88private import codeql.dataflow.internal.DataFlowImpl
99private import rust
10+ private import SsaImpl as SsaImpl
1011private import codeql.rust.controlflow.ControlFlowGraph
12+ private import codeql.rust.controlflow.CfgNodes
1113private import codeql.rust.dataflow.Ssa
1214
1315module Node {
@@ -52,18 +54,43 @@ module Node {
5254 override Location getLocation ( ) { none ( ) }
5355 }
5456
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+
5579 /**
5680 * The value of a parameter at function entry, viewed as a node in a data
5781 * flow graph.
5882 */
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 ) }
6187
62- ParameterNode ( ) { this = TSourceParameterNode ( param ) }
88+ override Location getLocation ( ) { result = parameter . getLocation ( ) }
6389
64- override Location getLocation ( ) { result = param . getLocation ( ) }
90+ override string toString ( ) { result = parameter . toString ( ) }
6591
66- override string toString ( ) { result = param .toString ( ) }
92+ /** Gets the parameter in the AST that this node corresponds to. */
93+ Param getParameter ( ) { result = parameter }
6794 }
6895
6996 final class ArgumentNode = NaNode ;
@@ -93,6 +120,32 @@ module Node {
93120 final class CastNode = NaNode ;
94121}
95122
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+
96149module RustDataFlow implements InputSig< Location > {
97150 /**
98151 * An element, viewed as a node in a data flow graph. Either an expression
@@ -122,10 +175,10 @@ module RustDataFlow implements InputSig<Location> {
122175
123176 predicate nodeIsHidden ( Node node ) { none ( ) }
124177
125- class DataFlowExpr = Void ;
178+ class DataFlowExpr = ExprCfgNode ;
126179
127180 /** Gets the node corresponding to `e`. */
128- Node exprNode ( DataFlowExpr e ) { none ( ) }
181+ Node exprNode ( DataFlowExpr e ) { result . getCfgNode ( ) = e }
129182
130183 final class DataFlowCall extends TNormalCall {
131184 private CallExpr c ;
@@ -191,7 +244,7 @@ module RustDataFlow implements InputSig<Location> {
191244 * Holds if there is a simple local flow step from `node1` to `node2`. These
192245 * are the value-preserving intra-callable flow steps.
193246 */
194- predicate simpleLocalFlowStep ( Node node1 , Node node2 , string model ) { none ( ) }
247+ predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo , string model ) { none ( ) }
195248
196249 /**
197250 * Holds if data can flow from `node1` to `node2` through a non-local step
@@ -256,7 +309,9 @@ module RustDataFlow implements InputSig<Location> {
256309 * `node2` must be visited along a flow path, then any type known for `node2`
257310 * must also apply to `node1`.
258311 */
259- predicate localMustFlowStep ( Node node1 , Node node2 ) { none ( ) }
312+ predicate localMustFlowStep ( Node node1 , Node node2 ) {
313+ SsaFlow:: localMustFlowStep ( _, node1 , node2 )
314+ }
260315
261316 class LambdaCallKind = Void ;
262317
@@ -267,7 +322,7 @@ module RustDataFlow implements InputSig<Location> {
267322 /** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
268323 predicate lambdaCall ( DataFlowCall call , LambdaCallKind kind , Node receiver ) { none ( ) }
269324
270- /** Extra data- flow steps needed for lambda flow analysis. */
325+ /** Extra data flow steps needed for lambda flow analysis. */
271326 predicate additionalLambdaFlowStep ( Node nodeFrom , Node nodeTo , boolean preservesValue ) { none ( ) }
272327
273328 predicate knownSourceModel ( Node source , string model ) { none ( ) }
@@ -286,8 +341,9 @@ cached
286341private module Cached {
287342 cached
288343 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 )
291347
292348 cached
293349 newtype TDataFlowCall = TNormalCall ( CallExpr c )
@@ -302,7 +358,9 @@ private module Cached {
302358
303359 /** This is the local flow predicate that is exposed. */
304360 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+ }
306364}
307365
308366import Cached
0 commit comments