Skip to content

Commit 1401cba

Browse files
committed
SILGen: Fudge emitProlog() to emit unreachable later
For some reason, doing it in the other order causes a crash. I suspect this is because we create new instructions below, but if there's no insertion point, the instruction is never added to a basic block.
1 parent 4a7b35d commit 1401cba

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
lines changed

lib/SILGen/SILGenProlog.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -443,19 +443,6 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
443443
uint16_t ArgNo = emitProlog(paramList, selfParam, resultType,
444444
DC, throws, throwsLoc);
445445

446-
// Emit an unreachable instruction if a parameter type is
447-
// uninhabited
448-
if (paramList) {
449-
for (auto *param : *paramList) {
450-
if (param->getType()->isStructurallyUninhabited()) {
451-
SILLocation unreachableLoc(param);
452-
unreachableLoc.markAsPrologue();
453-
B.createUnreachable(unreachableLoc);
454-
break;
455-
}
456-
}
457-
}
458-
459446
// Emit the capture argument variables. These are placed last because they
460447
// become the first curry level of the SIL function.
461448
assert((captureInfo.hasBeenComputed() ||
@@ -491,6 +478,19 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
491478
emitCaptureArguments(*this, DC->getGenericSignatureOfContext(),
492479
capture, ++ArgNo);
493480
}
481+
482+
// Emit an unreachable instruction if a parameter type is
483+
// uninhabited
484+
if (paramList) {
485+
for (auto *param : *paramList) {
486+
if (param->getType()->isStructurallyUninhabited()) {
487+
SILLocation unreachableLoc(param);
488+
unreachableLoc.markAsPrologue();
489+
B.createUnreachable(unreachableLoc);
490+
break;
491+
}
492+
}
493+
}
494494
}
495495

496496
static void emitIndirectResultParameters(SILGenFunction &SGF, Type resultType,

test/SILGen/functions_uninhabited_param.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,10 @@ func foo(baz: Never) -> Int { // expected-note {{'baz' is uninhabited, so this f
88
}
99

1010
func bar(baz: Never) -> Int {} // ok
11+
12+
// We used to crash when emitting the closure below.
13+
enum E {
14+
static func f(_: E) {}
15+
}
16+
17+
let _: (E.Type) -> (E) -> () = { s in { e in s.f(e) } }

0 commit comments

Comments
 (0)