Skip to content

Commit 5d67b81

Browse files
committed
Fix case calculation for SPE with zero-sized payload
1 parent 8da561c commit 5d67b81

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,9 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
557557
//
558558
// The above logic generalizes the following important cases:
559559
// * A payload with XIs will generally have enough to
560-
// encode all payloadcases. It will have no discriminator
561-
// case, so everything is effectively on "page zero."
560+
// encode all payload cases. If so, then it will have
561+
// no discriminator allocated, so the discriminator is
562+
// always treated as zero.
562563
// * If the payload has no XIs but is not zero-sized, then
563564
// we'll need a page one. That page will usually be
564565
// large enough to encode all non-payload cases.
@@ -586,13 +587,14 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
586587
unsigned nonPayloadCasesUsingXIs = PayloadCase.TI.getNumExtraInhabitants();
587588
int ComputedCase = 0;
588589
if (discriminator == 0) {
589-
// Discriminator is for a page that encodes payload (and maybe tag data too)
590+
// This is Page 0, which encodes payload case and some additional cases in Xis
590591
int XITag;
591592
if (!PayloadCase.TI.readExtraInhabitantIndex(reader, address, &XITag)) {
592593
return false;
593594
}
594595
ComputedCase = XITag < 0 ? 0 : XITag + 1;
595596
} else {
597+
// This is some other page, so the entire payload area is just a case index
596598
unsigned payloadTag;
597599
if (!reader.readInteger(address, PayloadSize, &payloadTag)) {
598600
return false;
@@ -602,10 +604,9 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
602604
? ValueWitnessFlags::MaxNumExtraInhabitants
603605
: (1UL << (PayloadSize * 8UL));
604606
ComputedCase =
605-
1
606-
+ nonPayloadCasesUsingXIs
607-
+ (discriminator - 1) * casesPerNonPayloadPage
608-
+ payloadTag;
607+
1 + nonPayloadCasesUsingXIs // Cases on page 0
608+
+ (discriminator - 1) * casesPerNonPayloadPage // Cases on other pages
609+
+ payloadTag; // Cases on this page
609610
}
610611
if (static_cast<unsigned>(ComputedCase) < getNumCases()) {
611612
*CaseIndex = ComputedCase;

validation-test/Reflection/reflect_nested_generic.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,29 @@ reflect(enum: Outer2.E<S2>.Inner.F<S3>??.none)
237237
//CHECK: Enum value:
238238
//CHECK-NEXT: (enum_value name=none index=1)
239239

240+
struct S4: P { var a: Bool = true }
241+
242+
reflect(enum: Outer2.E<S3>.Inner.F<S4>.b)
243+
244+
//CHECK: Reflecting an enum.
245+
//CHECK: Type reference:
246+
//CHECK: Type info:
247+
//CHECK-NEXT: (single_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=252 bitwise_takable=1
248+
//CHECK-NEXT: (case name=u index=0 offset=0
249+
//CHECK-NEXT: (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
250+
//CHECK-NEXT: (field name=a offset=0
251+
//CHECK-NEXT: (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
252+
//CHECK-NEXT: (field name=_value offset=0
253+
//CHECK-NEXT: (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1))))))
254+
//CHECK-NEXT: (case name=a index=1)
255+
//CHECK-NEXT: (case name=b index=2))
256+
257+
//CHECK: Mangled name: $s22reflect_nested_generic6Outer2V1EO1FOy_AA2S3V_AA2S4VG
258+
//CHECK: Demangled name: reflect_nested_generic.Outer2.E<reflect_nested_generic.S3>.F<reflect_nested_generic.S4>
259+
260+
//CHECK: Enum value:
261+
//CHECK-NEXT: (enum_value name=b index=2)
262+
240263
reflect(enum: Outer2.E<S1>.Inner.F<S2>.Innerer?.none)
241264

242265
//CHECK: Reflecting an enum.

0 commit comments

Comments
 (0)