Skip to content

Commit 683a7f4

Browse files
committed
SILOptimizer: Fix spurious 'unreachable code' warning when a failable initializer calls a never-returning function
This came up recently with the protocol-oriented integer work in the standard library. Fixes <https://bugs.swift.org/browse/SR-4673>.
1 parent 2d89a97 commit 683a7f4

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

lib/SILGen/SILGenConstructor.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
286286

287287
// Inject the self value into an optional if the constructor is failable.
288288
if (ctor->getFailability() != OTK_None) {
289-
selfValue = B.createEnum(ctor, selfValue,
289+
selfValue = B.createEnum(cleanupLoc, selfValue,
290290
getASTContext().getOptionalSomeDecl(),
291291
getLoweredLoadableType(resultType));
292292
}
@@ -306,7 +306,8 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
306306
// If this is a failable initializer, project out the payload.
307307
case OTK_Optional:
308308
case OTK_ImplicitlyUnwrappedOptional:
309-
returnAddress = B.createInitEnumDataAddr(ctor, completeReturnAddress,
309+
returnAddress = B.createInitEnumDataAddr(cleanupLoc,
310+
completeReturnAddress,
310311
getASTContext().getOptionalSomeDecl(),
311312
selfLV->getType());
312313
break;
@@ -320,7 +321,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
320321
// Inject the enum tag if the result is optional because of failability.
321322
if (ctor->getFailability() != OTK_None) {
322323
// Inject the 'Some' tag.
323-
B.createInjectEnumAddr(ctor, completeReturnAddress,
324+
B.createInjectEnumAddr(cleanupLoc, completeReturnAddress,
324325
getASTContext().getOptionalSomeDecl());
325326
}
326327
}

test/SILOptimizer/unreachable_code.swift

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -emit-sil %s -o /dev/null -verify
1+
// RUN: %target-swift-frontend -emit-sil -primary-file %s -o /dev/null -verify
22
func ifFalse() -> Int {
33
if false { // expected-note {{always evaluates to false}}
44
return 0 // expected-warning {{will never be executed}}
@@ -350,7 +350,7 @@ func testGuard(_ a : Int) {
350350
}
351351
}
352352

353-
public func testFailingCast(_ s:String) -> Int {
353+
func testFailingCast(_ s:String) -> Int {
354354
// There should be no notes or warnings about a call to a noreturn function, because we do not expose
355355
// how casts are lowered.
356356
return s as! Int // expected-warning {{cast from 'String' to unrelated type 'Int' always fails}}
@@ -419,14 +419,30 @@ while true {
419419

420420

421421
// SR-1010 - rdar://25278336 - Spurious "will never be executed" warnings when building standard library
422-
public struct SR1010<T> {
422+
struct SR1010<T> {
423423
var a : T
424424
}
425425

426426
extension SR1010 {
427427
@available(*, unavailable, message: "use the 'enumerated()' method on the sequence")
428-
public init(_ base: Int) {
428+
init(_ base: Int) {
429429
fatalError("unavailable function can't be called")
430430
}
431431
}
432432

433+
// More spurious 'will never be executed' warnings
434+
struct FailingStruct {
435+
init?(x: ()) {
436+
fatalError("gotcha")
437+
}
438+
}
439+
440+
class FailingClass {
441+
init?(x: ()) {
442+
fatalError("gotcha")
443+
}
444+
445+
convenience init?(y: ()) {
446+
fatalError("gotcha")
447+
}
448+
}

0 commit comments

Comments
 (0)