Skip to content

Commit 78edafc

Browse files
committed
Rust: Include patterns as data flow nodes
1 parent a277bcb commit 78edafc

File tree

3 files changed

+50
-18
lines changed

3 files changed

+50
-18
lines changed

rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ class AstCfgNode extends CfgNode {
1212
AstNode node;
1313

1414
AstCfgNode() { node = this.getAstNode() }
15+
16+
/** Gets the underlying ast node. */
17+
AstNode getAstNode() { result = node }
1518
}
1619

1720
/** A CFG node that corresponds to a parameter in the AST. */
@@ -22,6 +25,14 @@ class ParamCfgNode extends AstCfgNode {
2225
Param getParam() { result = node }
2326
}
2427

28+
/** A CFG node that corresponds to a parameter in the AST. */
29+
class PatCfgNode extends AstCfgNode {
30+
override Pat node;
31+
32+
/** Gets the underlying pattern. */
33+
Pat getPat() { result = node }
34+
}
35+
2536
/** A CFG node that corresponds to an expression in the AST. */
2637
class ExprCfgNode extends AstCfgNode {
2738
override Expr node;

rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ module Node {
123123
override Location getLocation() { none() }
124124
}
125125

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+
126139
/**
127140
* A node in the data flow graph that corresponds to an expression in the
128141
* AST.
@@ -131,39 +144,34 @@ module Node {
131144
* to multiple `ExprNode`s, just like it may correspond to multiple
132145
* `ControlFlow::Node`s.
133146
*/
134-
class ExprNode extends Node, TExprNode {
135-
ExprCfgNode n;
147+
class ExprNode extends AstCfgFlowNode, TExprNode {
148+
override ExprCfgNode n;
136149

137150
ExprNode() { this = TExprNode(n) }
138151

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+
}
142154

143-
override string toString() { result = n.getExpr().toString() }
155+
final class PatNode extends AstCfgFlowNode, TPatNode {
156+
override PatCfgNode n;
144157

145-
override Expr asExpr() { result = n.getExpr() }
158+
PatNode() { this = TPatNode(n) }
146159

147-
override CfgNode getCfgNode() { result = n }
160+
/** Gets the Pat in the AST that this node corresponds to. */
161+
Pat getPat() { result = n.getPat() }
148162
}
149163

150164
/**
151165
* The value of a parameter at function entry, viewed as a node in a data
152166
* flow graph.
153167
*/
154-
final class ParameterNode extends Node, TParameterNode {
155-
ParamCfgNode parameter;
168+
final class ParameterNode extends AstCfgFlowNode, TParameterNode {
169+
override ParamCfgNode n;
156170

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) }
164172

165173
/** Gets the parameter in the AST that this node corresponds to. */
166-
Param getParameter() { result = parameter.getParam() }
174+
Param getParameter() { result = n.getParam() }
167175
}
168176

169177
final class ArgumentNode = NaNode;
@@ -281,6 +289,11 @@ module LocalFlow {
281289
pragma[nomagic]
282290
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
283291
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+
)
284297
}
285298
}
286299

@@ -485,6 +498,7 @@ private module Cached {
485498
newtype TNode =
486499
TExprNode(ExprCfgNode n) or
487500
TParameterNode(ParamCfgNode p) or
501+
TPatNode(PatCfgNode p) or
488502
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node)
489503

490504
cached

rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
| main.rs:2:9:2:9 | [SSA] s | main.rs:3:33:3:33 | s |
2+
| main.rs:2:13:2:19 | "Hello" | main.rs:2:9:2:9 | s |
23
| main.rs:6:18:6:21 | [SSA] cond | main.rs:9:16:9:19 | cond |
34
| main.rs:7:9:7:9 | [SSA] a | main.rs:10:9:10:9 | a |
5+
| main.rs:7:13:7:13 | 1 | main.rs:7:9:7:9 | a |
46
| main.rs:8:9:8:9 | [SSA] b | main.rs:12:9:12:9 | b |
7+
| main.rs:8:13:8:13 | 2 | main.rs:8:9:8:9 | b |
58
| main.rs:9:9:9:9 | [SSA] c | main.rs:14:5:14:5 | c |
9+
| main.rs:9:13:13:5 | IfExpr | main.rs:9:9:9:9 | c |
610
| main.rs:9:21:11:5 | BlockExpr | main.rs:9:13:13:5 | IfExpr |
711
| main.rs:10:9:10:9 | a | main.rs:9:21:11:5 | BlockExpr |
812
| main.rs:11:12:13:5 | BlockExpr | main.rs:9:13:13:5 | IfExpr |
913
| main.rs:12:9:12:9 | b | main.rs:11:12:13:5 | BlockExpr |
1014
| main.rs:14:5:14:5 | c | main.rs:6:37:15:1 | BlockExpr |
1115
| main.rs:18:9:18:9 | [SSA] a | main.rs:20:15:20:15 | a |
16+
| main.rs:18:13:18:13 | 1 | main.rs:18:9:18:9 | a |
1217
| main.rs:19:9:19:9 | [SSA] b | main.rs:22:5:22:5 | b |
18+
| main.rs:19:13:21:5 | LoopExpr | main.rs:19:9:19:9 | b |
1319
| main.rs:20:9:20:15 | BreakExpr | main.rs:19:13:21:5 | LoopExpr |
1420
| main.rs:20:15:20:15 | a | main.rs:20:9:20:15 | BreakExpr |
1521
| main.rs:22:5:22:5 | b | main.rs:17:29:23:1 | BlockExpr |
22+
| main.rs:26:17:26:17 | 1 | main.rs:26:9:26:13 | i |
1623
| main.rs:27:5:27:5 | [SSA] i | main.rs:28:5:28:5 | i |
1724
| main.rs:27:5:27:5 | i | main.rs:27:5:27:5 | [SSA] i |
1825
| main.rs:28:5:28:5 | i | main.rs:25:24:29:1 | BlockExpr |

0 commit comments

Comments
 (0)