Skip to content

Commit 8e29f27

Browse files
authored
Merge pull request #59083 from xedin/rdar-93796211-5.7
[5.7][CSClosure] Fix crash in `fallthrough` statement checking
2 parents fec9add + 91160eb commit 8e29f27

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

lib/Sema/CSClosure.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,7 +1394,15 @@ class ClosureConstraintApplication
13941394
}
13951395

13961396
auto caseStmt = cast<CaseStmt>(rawCase.get<Stmt *>());
1397-
visitCaseStmt(caseStmt);
1397+
// Body of the `case` statement can contain a `fallthrough`
1398+
// statement that requires both source and destination
1399+
// `case` preambles to be type-checked, so bodies of `case`
1400+
// statements should be visited after preambles.
1401+
visitCaseStmtPreamble(caseStmt);
1402+
}
1403+
1404+
for (auto *caseStmt : switchStmt->getCases()) {
1405+
visitCaseStmtBody(caseStmt);
13981406

13991407
// Check restrictions on '@unknown'.
14001408
if (caseStmt->hasUnknownAttr()) {
@@ -1421,7 +1429,7 @@ class ClosureConstraintApplication
14211429
return doStmt;
14221430
}
14231431

1424-
ASTNode visitCaseStmt(CaseStmt *caseStmt) {
1432+
void visitCaseStmtPreamble(CaseStmt *caseStmt) {
14251433
// Translate the patterns and guard expressions for each case label item.
14261434
for (auto &caseItem : caseStmt->getMutableCaseLabelItems()) {
14271435
SolutionApplicationTarget caseTarget(&caseItem, closure);
@@ -1437,11 +1445,16 @@ class ClosureConstraintApplication
14371445
solution.getType(prev)->mapTypeOutOfContext());
14381446
expected->setInterfaceType(type);
14391447
}
1448+
}
14401449

1441-
// Translate the body.
1450+
void visitCaseStmtBody(CaseStmt *caseStmt) {
14421451
auto *newBody = visit(caseStmt->getBody()).get<Stmt *>();
14431452
caseStmt->setBody(cast<BraceStmt>(newBody));
1453+
}
14441454

1455+
ASTNode visitCaseStmt(CaseStmt *caseStmt) {
1456+
visitCaseStmtPreamble(caseStmt);
1457+
visitCaseStmtBody(caseStmt);
14451458
return caseStmt;
14461459
}
14471460

test/expr/closure/multi_statement.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,3 +404,23 @@ func test_type_finder_doesnt_walk_into_inner_closures() {
404404
return x
405405
}
406406
}
407+
408+
// rdar://93796211 (issue#59035) - crash during solution application to fallthrough statement
409+
func test_fallthrough_stmt() {
410+
{
411+
var collector: [Void] = []
412+
for _: Void in [] {
413+
switch (() as Void?, ()) {
414+
case (let a?, let b):
415+
// expected-warning@-1 {{constant 'b' inferred to have type '()', which may be unexpected}}
416+
// expected-note@-2 {{add an explicit type annotation to silence this warning}}
417+
collector.append(a)
418+
fallthrough
419+
case (nil, let b):
420+
// expected-warning@-1 {{constant 'b' inferred to have type '()', which may be unexpected}}
421+
// expected-note@-2 {{add an explicit type annotation to silence this warning}}
422+
collector.append(b)
423+
}
424+
}
425+
}()
426+
}

0 commit comments

Comments
 (0)