Skip to content

Commit 22edece

Browse files
committed
Rust: Add CFG construction for if let expressions
1 parent 20e9687 commit 22edece

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
9494
class MatchCompletion extends TMatchCompletion, ConditionalCompletion {
9595
MatchCompletion() { this = TMatchCompletion(value) }
9696

97-
override predicate isValidForSpecific(AstNode e) { e = any(MatchArm arm).getPat() }
97+
override predicate isValidForSpecific(AstNode e) { e instanceof Pat }
9898

9999
override MatchSuccessor getAMatchingSuccessorType() { result.getValue() = value }
100100

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,15 +204,21 @@ class IfExprTree extends PostOrderTree instanceof IfExpr {
204204
child = [super.getCondition(), super.getThen(), super.getElse()]
205205
}
206206

207+
ConditionalCompletion conditionCompletion(Completion c) {
208+
if super.getCondition() instanceof LetExpr
209+
then result = c.(MatchCompletion)
210+
else result = c.(BooleanCompletion)
211+
}
212+
207213
override predicate succ(AstNode pred, AstNode succ, Completion c) {
208214
// Edges from the condition to the branches
209215
last(super.getCondition(), pred, c) and
210216
(
211-
first(super.getThen(), succ) and c.(BooleanCompletion).succeeded()
217+
first(super.getThen(), succ) and this.conditionCompletion(c).succeeded()
212218
or
213-
first(super.getElse(), succ) and c.(BooleanCompletion).failed()
219+
first(super.getElse(), succ) and this.conditionCompletion(c).failed()
214220
or
215-
not super.hasElse() and succ = this and c.(BooleanCompletion).failed()
221+
not super.hasElse() and succ = this and this.conditionCompletion(c).failed()
216222
)
217223
or
218224
// An edge from the then branch to the last node
@@ -235,8 +241,11 @@ class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr {
235241
}
236242
}
237243

238-
class LetExprTree extends StandardPostOrderTree instanceof LetExpr {
239-
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() }
244+
// `LetExpr` is a pre-order tree such that the pattern itself ends up
245+
// dominating successors in the graph in the same way that patterns do in
246+
// `match` expressions.
247+
class LetExprTree extends StandardPreOrderTree instanceof LetExpr {
248+
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getPat() }
240249
}
241250

242251
// We handle `let` statements with trivial patterns separately as they don't

0 commit comments

Comments
 (0)