Skip to content

Commit 2c65f5d

Browse files
committed
SILGen: Don't emit unreachable code warnings for explicit return statement
1 parent e79119d commit 2c65f5d

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

lib/SILGen/SILGenStmt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,9 @@ void StmtEmitter::visitReturnStmt(ReturnStmt *S) {
404404
if (!S->hasResult())
405405
// Void return.
406406
SGF.Cleanups.emitBranchAndCleanups(SGF.ReturnDest, Loc);
407+
else if (S->getResult()->getType()->isUninhabited())
408+
// Never return.
409+
SGF.emitIgnoredExpr(S->getResult());
407410
else
408411
SGF.emitReturnExpr(Loc, S->getResult());
409412
}

lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,20 @@ static SILInstruction *getAsCallToNoReturn(SILInstruction *I) {
423423
if (BI->getModule().isNoReturnBuiltinOrIntrinsic(BI->getName()))
424424
return BI;
425425
}
426+
427+
// These appear in accessors for stored properties with uninhabited
428+
// type. Since a type containing an uninhabited stored property is
429+
// itself uninhabited, we treat these identically to fatalError(), etc.
430+
if (auto *SEI = dyn_cast<StructExtractInst>(I)) {
431+
if (SEI->getType().getASTType()->isUninhabited())
432+
return SEI;
433+
}
434+
435+
if (auto *SEAI = dyn_cast<StructElementAddrInst>(I)) {
436+
if (SEAI->getType().getASTType()->isUninhabited())
437+
return SEAI;
438+
}
439+
426440
return nullptr;
427441
}
428442

test/SILOptimizer/unreachable_code.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,3 +374,37 @@ struct SillyStruct {
374374
takesInOut(value: &self)
375375
}
376376
}
377+
378+
// This triggers various problems
379+
public func genericMightBeNever<R>(
380+
_ body: () -> R) -> R {
381+
while true {}
382+
383+
}
384+
385+
func sillyGenericExample() -> Never {
386+
return genericMightBeNever {
387+
return genericMightBeNever {
388+
return fatalError()
389+
}
390+
}
391+
}
392+
393+
// https://bugs.swift.org/browse/SR-7472
394+
395+
protocol P {
396+
static var theThing: Self { get }
397+
}
398+
399+
extension Never : P {
400+
static var theThing: Never { return fatalError() }
401+
}
402+
403+
func test<T: P>(_ type: T.Type) -> T {
404+
return type.theThing
405+
}
406+
407+
func f(i: Int?) {
408+
guard i != nil else { Never.theThing }
409+
guard i != nil else { test(Never.self) }
410+
}

0 commit comments

Comments
 (0)