Skip to content

Commit 2d1c62b

Browse files
committed
Rust: Fix dead end in CFG for empty tuple and struct patterns
1 parent b97ec40 commit 2d1c62b

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,8 @@ module PatternTrees {
612612
result = rank[i + 1](Pat pat, int j | pat = this.getPat(j) | pat order by j)
613613
}
614614

615+
predicate isEmpty() { not any(Pat p) = this.getPat(0) }
616+
615617
override predicate propagatesAbnormal(AstNode child) { child = this.getPatRanked(_) }
616618

617619
override predicate succ(AstNode pred, AstNode succ, Completion c) {
@@ -629,8 +631,11 @@ module PatternTrees {
629631

630632
override predicate last(AstNode node, Completion c) {
631633
node = this and
632-
completionIsValidFor(c, this) and
633-
c.(MatchCompletion).failed()
634+
(
635+
completionIsValidFor(c, this) and c.(MatchCompletion).failed()
636+
or
637+
this.isEmpty() and node = this and c.(MatchCompletion).succeeded()
638+
)
634639
or
635640
exists(int i | last(this.getPatRanked(i), node, c) |
636641
c.(MatchCompletion).failed()

rust/ql/test/library-tests/controlflow/Cfg.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,14 +633,23 @@ edges
633633
| test.rs:282:13:282:24 | PathPat | test.rs:282:29:282:29 | 5 | match |
634634
| test.rs:282:29:282:29 | 5 | test.rs:276:9:283:9 | MatchExpr | |
635635
| test.rs:289:5:292:5 | enter empty_tuple_pattern | test.rs:289:28:289:31 | unit | |
636+
| test.rs:289:5:292:5 | exit empty_tuple_pattern (normal) | test.rs:289:5:292:5 | exit empty_tuple_pattern | |
636637
| test.rs:289:28:289:31 | unit | test.rs:289:28:289:35 | Param | match |
637638
| test.rs:289:28:289:35 | Param | test.rs:290:9:290:22 | LetStmt | |
638639
| test.rs:290:9:290:22 | LetStmt | test.rs:290:18:290:21 | unit | |
640+
| test.rs:290:13:290:14 | TuplePat | test.rs:291:9:291:15 | ExprStmt | match |
639641
| test.rs:290:18:290:21 | unit | test.rs:290:13:290:14 | TuplePat | |
642+
| test.rs:291:9:291:14 | ReturnExpr | test.rs:289:5:292:5 | exit empty_tuple_pattern (normal) | return |
643+
| test.rs:291:9:291:15 | ExprStmt | test.rs:291:9:291:14 | ReturnExpr | |
640644
| test.rs:296:5:300:5 | enter empty_struct_pattern | test.rs:296:29:296:30 | st | |
645+
| test.rs:296:5:300:5 | exit empty_struct_pattern (normal) | test.rs:296:5:300:5 | exit empty_struct_pattern | |
641646
| test.rs:296:29:296:30 | st | test.rs:296:29:296:40 | Param | match |
642647
| test.rs:296:29:296:40 | Param | test.rs:297:15:297:16 | st | |
648+
| test.rs:296:50:300:5 | BlockExpr | test.rs:296:5:300:5 | exit empty_struct_pattern (normal) | |
649+
| test.rs:297:9:299:9 | MatchExpr | test.rs:296:50:300:5 | BlockExpr | |
643650
| test.rs:297:15:297:16 | st | test.rs:298:13:298:23 | RecordPat | |
651+
| test.rs:298:13:298:23 | RecordPat | test.rs:298:28:298:28 | 1 | match |
652+
| test.rs:298:28:298:28 | 1 | test.rs:297:9:299:9 | MatchExpr | |
644653
| test.rs:304:5:309:5 | enter test_infinite_loop | test.rs:305:9:307:9 | ExprStmt | |
645654
| test.rs:305:9:307:9 | ExprStmt | test.rs:306:13:306:13 | 1 | |
646655
| test.rs:305:14:307:9 | BlockExpr | test.rs:306:13:306:13 | 1 | |

0 commit comments

Comments
 (0)