Skip to content

Commit 455f3dc

Browse files
committed
AST: Clang enum elements can't be unavailable during lowering.
There aren't sufficiently strong compiler checks that would prevent unavailable elements of clang enums from being instantiated at runtime, so don't consider any clang enum elements as unavailable during lowering. Since there aren't any symbols associated with clang enum elements, we don't have to worry about linker failures that might result from leaving references to them in SIL.
1 parent 29374cb commit 455f3dc

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

lib/AST/Availability.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ bool Decl::isAvailableDuringLowering() const {
312312
UnavailableDeclOptimization::Complete)
313313
return true;
314314

315+
if (hasClangNode())
316+
return true;
317+
315318
return !isUnconditionallyUnavailable(this);
316319
}
317320

test/SILOptimizer/Inputs/switch_enum_objc.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,18 @@ enum Coin {
1212
CoinHeads,
1313
CoinTails
1414
} __attribute__((enum_extensibility(closed)));
15+
16+
// Swift should preserve branches matching the unavailable elements in clang
17+
// enums since there are not strong compiler protections preventing these values
18+
// from being instantiated at runtime.
19+
20+
enum Dimension {
21+
DimensionX __attribute__((swift_name("x"))),
22+
DimensionY __attribute__((swift_name("y"))),
23+
DimensionZ __attribute__((swift_name("z"))) __attribute__((unavailable)),
24+
} __attribute__((enum_extensibility(open)));
25+
26+
enum UnfairCoin {
27+
UnfairCoinHeads,
28+
UnfairCoinTails __attribute__((unavailable)),
29+
} __attribute__((enum_extensibility(closed)));
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-emit-sil -module-name Test -parse-as-library %s -verify -unavailable-decl-optimization=none -Onone -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/switch_enum_objc.h | %FileCheck %s
2+
// RUN: %target-swift-emit-sil -module-name Test -parse-as-library %s -verify -unavailable-decl-optimization=complete -Onone -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/switch_enum_objc.h | %FileCheck %s
3+
4+
// CHECK-LABEL: sil @$s4Test30testFullyCoveredSwitchOpenEnumyySo9DimensionVF : $@convention(thin) (Dimension) -> () {
5+
// CHECK: switch_enum %0 : $Dimension, case #Dimension.x!enumelt: [[XBB:bb[0-9]+]], case #Dimension.z!enumelt: [[ZBB:bb[0-9]+]], case #Dimension.y!enumelt: [[YBB:bb[0-9]+]], default [[DEFAULTBB:bb[0-9]+]]
6+
// CHECK: [[ZBB]]:
7+
// CHECK-NOT: unreachable
8+
// CHECK: [[YBB]]:
9+
// CHECK: } // end sil function '$s4Test30testFullyCoveredSwitchOpenEnumyySo9DimensionVF'
10+
public func testFullyCoveredSwitchOpenEnum(_ e: Dimension) {
11+
switch e {
12+
case .x: ()
13+
case .z: ()
14+
case .y: ()
15+
}
16+
}
17+
18+
// CHECK-LABEL: sil @$s4Test32testFullyCoveredSwitchClosedEnumyySo10UnfairCoinVF : $@convention(thin) (UnfairCoin) -> () {
19+
// CHECK: switch_enum %0 : $UnfairCoin, case #UnfairCoin.heads!enumelt: [[HEADSBB:bb[0-9]+]], case #UnfairCoin.tails!enumelt: [[TAILSBB:bb[0-9]+]], default [[DEFAULTBB:bb[0-9]+]]
20+
// CHECK: [[TAILSBB]]:
21+
// CHECK-NOT: unreachable
22+
// CHECK: [[DEFAULTBB]]:
23+
// CHECK: } // end sil function '$s4Test32testFullyCoveredSwitchClosedEnumyySo10UnfairCoinVF'
24+
public func testFullyCoveredSwitchClosedEnum(_ e: UnfairCoin) {
25+
switch e {
26+
case .heads: ()
27+
case .tails: ()
28+
}
29+
}

0 commit comments

Comments
 (0)