Skip to content

Commit d0f978d

Browse files
authored
Merge pull request #17749 from paldepind/rust-cfg-handle-question-mark
Rust: Handle question mark operator in CFG
2 parents de61296 + e83f1d1 commit d0f978d

File tree

4 files changed

+228
-142
lines changed

4 files changed

+228
-142
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ class SimpleCompletion extends NormalCompletion, TSimpleCompletion {
3636

3737
// `SimpleCompletion` is the "default" completion type, thus it is valid for
3838
// any node where there isn't another more specific completion type.
39-
override predicate isValidFor(AstNode e) { not any(Completion c).isValidForSpecific(e) }
39+
override predicate isValidFor(AstNode e) {
40+
not any(Completion c).isValidForSpecific(e)
41+
or
42+
// A `?` expression can both proceed normally or cause an early return, so
43+
// we explicitly allow the former here.
44+
e instanceof TryExpr
45+
}
4046

4147
override string toString() { result = "simple" }
4248
}
@@ -204,7 +210,9 @@ class ContinueCompletion extends TContinueCompletion, Completion {
204210
class ReturnCompletion extends TReturnCompletion, Completion {
205211
override ReturnSuccessor getAMatchingSuccessorType() { any() }
206212

207-
override predicate isValidForSpecific(AstNode e) { e instanceof ReturnExpr }
213+
override predicate isValidForSpecific(AstNode e) {
214+
e instanceof ReturnExpr or e instanceof TryExpr
215+
}
208216

209217
override string toString() { result = "return" }
210218
}

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

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,8 @@ class MatchExprTree extends PostOrderTree instanceof MatchExpr {
504504
override predicate succ(AstNode pred, AstNode succ, Completion c) {
505505
// Edge from the scrutinee to the first arm.
506506
last(super.getExpr(), pred, c) and
507-
first(super.getArm(0).getPat(), succ)
507+
first(super.getArm(0).getPat(), succ) and
508+
completionIsNormal(c)
508509
or
509510
// Edge from a failed match/guard in one arm to the beginning of the next arm.
510511
exists(int i |
@@ -571,18 +572,12 @@ class RefExprTree extends StandardPostOrderTree instanceof RefExpr {
571572
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
572573
}
573574

574-
class ReturnExprTree extends PostOrderTree instanceof ReturnExpr {
575-
override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() }
576-
577-
override predicate first(AstNode node) {
578-
first(super.getExpr(), node)
579-
or
580-
not super.hasExpr() and node = this
581-
}
575+
class ReturnExprTree extends StandardPostOrderTree instanceof ReturnExpr {
576+
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
577+
}
582578

583-
override predicate succ(AstNode pred, AstNode succ, Completion c) {
584-
last(super.getExpr(), pred, c) and succ = this and completionIsNormal(c)
585-
}
579+
class TryExprTree extends StandardPostOrderTree instanceof TryExpr {
580+
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
586581
}
587582

588583
class TupleExprTree extends StandardPostOrderTree instanceof TupleExpr {

0 commit comments

Comments
 (0)