Skip to content

Commit 0c6b4cd

Browse files
authored
Merge pull request github#18078 from hvitved/rust/variant-flow
Rust: Data flow through variants
2 parents 047e974 + 8c11138 commit 0c6b4cd

File tree

10 files changed

+829
-243
lines changed

10 files changed

+829
-243
lines changed

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,37 @@ final class RecordExprCfgNode extends Nodes::RecordExprCfgNode {
187187

188188
RecordExprCfgNode() { node = this.getRecordExpr() }
189189

190-
/** Gets the `i`th record expression. */
191-
ExprCfgNode getExpr(int i) {
192-
any(ChildMapping mapping)
193-
.hasCfgChild(node, node.getRecordExprFieldList().getField(i).getExpr(), this, result)
190+
/** Gets the record expression for the field `field`. */
191+
pragma[nomagic]
192+
ExprCfgNode getFieldExpr(string field) {
193+
exists(RecordExprField ref |
194+
ref = node.getRecordExprFieldList().getAField() and
195+
any(ChildMapping mapping).hasCfgChild(node, ref.getExpr(), this, result) and
196+
field = ref.getNameRef().getText()
197+
)
198+
}
199+
}
200+
201+
/**
202+
* A record pattern. For example:
203+
* ```rust
204+
* match x {
205+
* Foo { a: 1, b: 2 } => "ok",
206+
* Foo { .. } => "fail",
207+
* }
208+
* ```
209+
*/
210+
final class RecordPatCfgNode extends Nodes::RecordPatCfgNode {
211+
private RecordPatChildMapping node;
212+
213+
RecordPatCfgNode() { node = this.getRecordPat() }
214+
215+
/** Gets the record pattern for the field `field`. */
216+
PatCfgNode getFieldPat(string field) {
217+
exists(RecordPatField rpf |
218+
rpf = node.getRecordPatFieldList().getAField() and
219+
any(ChildMapping mapping).hasCfgChild(node, rpf.getPat(), this, result) and
220+
field = rpf.getNameRef().getText()
221+
)
194222
}
195223
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ class RecordExprChildMapping extends ParentAstNode, RecordExpr {
6868
}
6969
}
7070

71+
class RecordPatChildMapping extends ParentAstNode, RecordPat {
72+
override predicate relevantChild(AstNode child) {
73+
child = this.getRecordPatFieldList().getAField().getPat()
74+
}
75+
}
76+
7177
class FormatArgsExprChildMapping extends ParentAstNode, CfgImpl::ExprTrees::FormatArgsExprTree {
7278
override predicate relevantChild(AstNode child) { child = this.getChildNode(_) }
7379
}

rust/ql/lib/codeql/rust/dataflow/DataFlow.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ module DataFlow {
1919

2020
final class PostUpdateNode = Node::PostUpdateNode;
2121

22+
final class Content = DataFlowImpl::Content;
23+
24+
final class VariantContent = DataFlowImpl::VariantContent;
25+
26+
final class ContentSet = DataFlowImpl::ContentSet;
27+
2228
/**
2329
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
2430
* (intra-procedural) step.

0 commit comments

Comments
 (0)