Skip to content

Commit 1532355

Browse files
authored
Merge pull request #20528 from theblixguy/fix/SR-8435
[SILGen] Insert an unreachable if a function declaration's parameter is uninhabited
2 parents 6c20ff3 + 5587edf commit 1532355

File tree

4 files changed

+35
-0
lines changed

4 files changed

+35
-0
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ ERROR(guard_body_must_not_fallthrough,none,
229229
"'guard' body must not fall through, consider using a 'return' or 'throw'"
230230
" to exit the scope", ())
231231
WARNING(unreachable_code,none, "will never be executed", ())
232+
NOTE(unreachable_code_uninhabited_param_note,none,
233+
"'%0' is uninhabited, so this function body can never be executed", (StringRef))
232234
NOTE(unreachable_code_branch,none,
233235
"condition always evaluates to %select{false|true}0", (bool))
234236
NOTE(call_to_noreturn_note,none,

lib/SILGen/SILGenProlog.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,19 @@ void SILGenFunction::emitProlog(AnyFunctionRef TheClosure,
423423
Type resultType, bool throws) {
424424
uint16_t ArgNo = emitProlog(paramList, selfParam, resultType,
425425
TheClosure.getAsDeclContext(), throws);
426+
427+
// Emit an unreachable instruction if a parameter type is
428+
// uninhabited
429+
if (paramList) {
430+
for (auto *param : *paramList) {
431+
if (param->getType()->isStructurallyUninhabited()) {
432+
SILLocation unreachableLoc(param);
433+
unreachableLoc.markAsPrologue();
434+
B.createUnreachable(unreachableLoc);
435+
break;
436+
}
437+
}
438+
}
426439

427440
// Emit the capture argument variables. These are placed last because they
428441
// become the first curry level of the SIL function.

lib/SILGen/SILGenStmt.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,16 @@ void StmtEmitter::visitBraceStmt(BraceStmt *S) {
318318
} else {
319319
diagnose(getASTContext(), ESD.getStartLoc(),
320320
diag::unreachable_code);
321+
if (!S->getElements().empty()) {
322+
for (auto *arg : SGF.getFunction().getArguments()) {
323+
if (arg->getType().getASTType()->isStructurallyUninhabited()) {
324+
diagnose(getASTContext(), S->getStartLoc(),
325+
diag::unreachable_code_uninhabited_param_note,
326+
arg->getDecl()->getBaseName().userFacingName());
327+
break;
328+
}
329+
}
330+
}
321331
}
322332
return;
323333
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-emit-sil -enable-sil-ownership %s -o /dev/null -verify
2+
3+
//===--- Function declaration with uninhabited parameter type
4+
5+
func foo(baz: Never) -> Int { // expected-note {{'baz' is uninhabited, so this function body can never be executed}}
6+
print("I can't be called!") // expected-warning{{will never be executed}}
7+
return 0
8+
}
9+
10+
func bar(baz: Never) -> Int {} // ok

0 commit comments

Comments
 (0)