Skip to content

Commit 83692bb

Browse files
committed
Reflection: Fix bug where presence of a no-payload enum resets field offsets back to zero for subsequent fields
The alignment was set to 0, which messed up the record layout computations. Add an assert to catch this in the future. Fixes <rdar://problem/29115967>.
1 parent 71364d0 commit 83692bb

File tree

3 files changed

+10
-6
lines changed

3 files changed

+10
-6
lines changed

include/swift/Reflection/TypeLowering.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ class TypeInfo {
117117
unsigned Size, unsigned Alignment,
118118
unsigned Stride, unsigned NumExtraInhabitants)
119119
: Kind(Kind), Size(Size), Alignment(Alignment), Stride(Stride),
120-
NumExtraInhabitants(NumExtraInhabitants) {}
120+
NumExtraInhabitants(NumExtraInhabitants) {
121+
assert(Alignment > 0);
122+
}
121123

122124
TypeInfoKind getKind() const { return Kind; }
123125

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ class ExistentialTypeInfoBuilder {
378378
unsigned RecordTypeInfoBuilder::addField(unsigned fieldSize,
379379
unsigned fieldAlignment,
380380
unsigned numExtraInhabitants) {
381+
assert(fieldAlignment > 0);
382+
381383
// Align the current size appropriately
382384
Size = ((Size + fieldAlignment - 1) & ~(fieldAlignment - 1));
383385

@@ -873,7 +875,7 @@ class EnumTypeInfoBuilder {
873875

874876
public:
875877
EnumTypeInfoBuilder(TypeConverter &TC)
876-
: TC(TC), Size(0), Alignment(0), NumExtraInhabitants(0),
878+
: TC(TC), Size(0), Alignment(1), NumExtraInhabitants(0),
877879
Kind(RecordKind::Invalid), Invalid(false) {}
878880

879881
const TypeInfo *build(const TypeRef *TR, const FieldDescriptor *FD) {

test/Reflection/typeref_lowering.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -913,11 +913,11 @@ V12TypeLowering10EnumStruct
913913
// CHECK-64: (struct TypeLowering.EnumStruct)
914914
// CHECK-64-NEXT: (struct size=81 alignment=8 stride=88 num_extra_inhabitants=0
915915
// CHECK-64-NEXT: (field name=empty offset=0
916-
// CHECK-64-NEXT: (no_payload_enum size=0 alignment=0 stride=1 num_extra_inhabitants=0))
916+
// CHECK-64-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0))
917917
// CHECK-64-NEXT: (field name=noPayload offset=0
918-
// CHECK-64-NEXT: (no_payload_enum size=1 alignment=0 stride=1 num_extra_inhabitants=0))
919-
// CHECK-64-NEXT: (field name=sillyNoPayload offset=0
920-
// CHECK-64-NEXT: (no_payload_enum size=1 alignment=0 stride=1 num_extra_inhabitants=0))
918+
// CHECK-64-NEXT: (no_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0))
919+
// CHECK-64-NEXT: (field name=sillyNoPayload offset=1
920+
// CHECK-64-NEXT: (no_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0))
921921
// CHECK-64-NEXT: (field name=singleton offset=8
922922
// CHECK-64-NEXT: (reference kind=strong refcounting=native))
923923
// CHECK-64-NEXT: (field name=singlePayload offset=16

0 commit comments

Comments
 (0)