Skip to content

Commit 6ed4eba

Browse files
committed
IRGen: Add missing forwarding stub in FixedEnumImplStrategy.
Without this, fixed-sized, address-only enums failed to correctly delegate their `getFixedExtraInhabitantMask` implementation to the enum layout strategy, causing a miscompile where switches would test undefined bits of the enum payload. Fixes rdar://problem/24885747.
1 parent 9187839 commit 6ed4eba

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4855,6 +4855,10 @@ namespace {
48554855
const override {
48564856
return Strategy.getFixedExtraInhabitantValue(IGM, bits, index);
48574857
}
4858+
4859+
APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override {
4860+
return Strategy.getFixedExtraInhabitantMask(IGM);
4861+
}
48584862
};
48594863

48604864
/// TypeInfo for loadable enum types.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %target-swift-frontend -emit-ir %s | FileCheck %s
2+
sil_stage canonical
3+
4+
enum Optional<T> { case Some(T), None }
5+
6+
class AClass {
7+
}
8+
9+
protocol AProto {
10+
}
11+
12+
enum AnEnum {
13+
case ACase(a: AClass, b: AProto)
14+
}
15+
16+
// CHECK-LABEL: define {{.*}} @switch_singleton_enum_in_optional
17+
// CHECK: [[CAST:%.*]] = bitcast {{.*}} %0 to { [[WORD:i[0-9]+]], [[WORD]], [[WORD]], [[WORD]], [[WORD]], [[WORD]] }*
18+
// CHECK: [[GEP:%.*]] = getelementptr {{.*}} %1, i32 0, i32 0
19+
// CHECK: [[FIRSTWORD:%.*]] = load [[WORD]], [[WORD]]* [[GEP]]
20+
// CHECK: [[TEST:%.*]] = icmp eq [[WORD]] [[FIRSTWORD]], 0
21+
// CHECK: br i1 [[TEST]]
22+
sil public @switch_singleton_enum_in_optional :
23+
$@convention(thin) (@in Optional<AnEnum>) -> () {
24+
entry(%a : $*Optional<AnEnum>):
25+
switch_enum_addr %a : $*Optional<AnEnum>,
26+
case #Optional.Some!enumelt.1: some,
27+
case #Optional.None!enumelt: none
28+
some:
29+
unreachable
30+
none:
31+
unreachable
32+
}
33+
34+
sil_vtable AClass {}

0 commit comments

Comments
 (0)