Skip to content

Commit b3668f8

Browse files
authored
Merge pull request github#17971 from paldepind/rust-df-patterns
Rust: Include patterns as data flow nodes
2 parents 2307df4 + 1a198bf commit b3668f8

File tree

4 files changed

+52
-19
lines changed

4 files changed

+52
-19
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
@@ -111,6 +111,19 @@ module Node {
111111
override Location getLocation() { none() }
112112
}
113113

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+
114127
/**
115128
* A node in the data flow graph that corresponds to an expression in the
116129
* AST.
@@ -119,39 +132,34 @@ module Node {
119132
* to multiple `ExprNode`s, just like it may correspond to multiple
120133
* `ControlFlow::Node`s.
121134
*/
122-
class ExprNode extends Node, TExprNode {
123-
ExprCfgNode n;
135+
class ExprNode extends AstCfgFlowNode, TExprNode {
136+
override ExprCfgNode n;
124137

125138
ExprNode() { this = TExprNode(n) }
126139

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

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

133-
override Expr asExpr() { result = n.getExpr() }
146+
PatNode() { this = TPatNode(n) }
134147

135-
override CfgNode getCfgNode() { result = n }
148+
/** Gets the Pat in the AST that this node corresponds to. */
149+
Pat getPat() { result = n.getPat() }
136150
}
137151

138152
/**
139153
* The value of a parameter at function entry, viewed as a node in a data
140154
* flow graph.
141155
*/
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;
146158

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

153161
/** Gets the parameter in the AST that this node corresponds to. */
154-
Param getParameter() { result = parameter.getParam() }
162+
Param getParameter() { result = n.getParam() }
155163
}
156164

157165
final class ArgumentNode = NaNode;
@@ -269,6 +277,11 @@ module LocalFlow {
269277
pragma[nomagic]
270278
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
271279
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+
)
272285
}
273286
}
274287

@@ -481,6 +494,7 @@ private module Cached {
481494
newtype TNode =
482495
TExprNode(ExprCfgNode n) or
483496
TParameterNode(ParamCfgNode p) or
497+
TPatNode(PatCfgNode p) or
484498
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node)
485499

486500
cached

rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ uniqueNodeLocation
44
| file://:0:0:0:0 | BlockExpr | Node should have one location but has 0. |
55
| file://:0:0:0:0 | Param | Node should have one location but has 0. |
66
| file://:0:0:0:0 | path | Node should have one location but has 0. |
7+
| file://:0:0:0:0 | path | Node should have one location but has 0. |
78
missingLocation
8-
| Nodes without location: 5 |
9+
| Nodes without location: 6 |

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)