Skip to content

Commit 7f7530f

Browse files
committed
[Statement checking] Fix "old" fallthrough source.
Fallthrough statement sources have always been incorrectly computed when there are nested switch statements. The recent refactoring to switch fallthrough source/destination computation over to ASTScope fixed the computation. Amusingly, the assertion that ensures that the old and new implementations produce the same result fires on these cases, but it's the old implementation that's wrong. Fix up the old implementation so the assertion does not trigger. The new test case crashes in Swift 5.3 and earlier, asserts prior to this change. Fixes rdar://problem/67704651.
1 parent cabcbc9 commit 7f7530f

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,12 +725,16 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
725725

726726
struct AddSwitchNest {
727727
StmtChecker &SC;
728+
CaseStmt *OuterFallthroughSource;
728729
CaseStmt *OuterFallthroughDest;
729-
AddSwitchNest(StmtChecker &SC) : SC(SC),
730+
AddSwitchNest(StmtChecker &SC)
731+
: SC(SC),
732+
OuterFallthroughSource(SC.FallthroughSource),
730733
OuterFallthroughDest(SC.FallthroughDest) {
731734
}
732735

733736
~AddSwitchNest() {
737+
SC.FallthroughSource = OuterFallthroughSource;
734738
SC.FallthroughDest = OuterFallthroughDest;
735739
}
736740
};

test/SILGen/switch_fallthrough.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,20 @@ func test5() {
165165
e()
166166
}
167167

168+
// rdar://problem/67704651 - crash due to nested fallthrough
169+
func testNestedFallthrough(x: (Int, String), y: (Int, Int)) {
170+
switch x {
171+
case (17, let s):
172+
switch y {
173+
case (42, let i):
174+
print("the answer")
175+
default:
176+
print("nope")
177+
}
178+
fallthrough
179+
case (42, let s):
180+
print("42 and \(s)")
181+
default:
182+
print("done")
183+
}
184+
}

0 commit comments

Comments
 (0)