mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Unavailable enum elements cannot be instantiated at runtime without invoking UB. Therefore the optimizer can consider a basic block unreachable if its only predecessor is a block that terminates in a switch instruction matching an unavailable enum element. Furthermore, removing the switch instruction cases that refer to unavailable enum elements is _mandatory_ when `-unavailable-decl-optimization=complete` is specified because otherwise lowered IR for these instructions could refer to enum tag accessors that will not be lowered, resulting in a failure during linking. Resolves rdar://113872720.
44 lines
1.1 KiB
Swift
44 lines
1.1 KiB
Swift
// RUN: %target-swift-frontend -emit-sil -unavailable-decl-optimization=none -verify %s
|
|
// RUN: %target-swift-frontend -emit-sil -unavailable-decl-optimization=complete -verify %s
|
|
|
|
public enum HasUnavailableElement {
|
|
case available
|
|
|
|
@available(*, unavailable)
|
|
case unavailable
|
|
}
|
|
|
|
public func markUsed<T>(_ t: T) {}
|
|
|
|
public func testSwitch(_ e: HasUnavailableElement) {
|
|
switch e {
|
|
case .available:
|
|
()
|
|
case .unavailable:
|
|
let x: Int // expected-note {{constant defined here}}
|
|
markUsed(x) // expected-error {{constant 'x' used before being initialized}}
|
|
}
|
|
}
|
|
|
|
public func testIfCase(_ e: HasUnavailableElement) {
|
|
if case .unavailable = e {
|
|
let x: Int // expected-note {{constant defined here}}
|
|
markUsed(x) // expected-error {{constant 'x' used before being initialized}}
|
|
}
|
|
}
|
|
|
|
public func testInitSwitch() {
|
|
struct S {
|
|
var x: Int // expected-note {{'self.x' not initialized}}
|
|
|
|
init(_ e: HasUnavailableElement) {
|
|
switch e {
|
|
case .available:
|
|
x = 1
|
|
case .unavailable:
|
|
()
|
|
}
|
|
} // expected-error {{return from initializer without initializing all stored properties}}
|
|
}
|
|
}
|