Skip to content

Commit 7ac7d55

Browse files
authored
Merge pull request #72290 from tbkka/tbkka-rdar123727657
Fix enum inspection of a no-payload enum inside another enum
2 parents 7196c9c + afb75e6 commit 7ac7d55

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,21 @@ class TrivialEnumTypeInfo: public EnumTypeInfo {
450450
}
451451
};
452452

453+
// Given a count, return a mask that is just
454+
// big enough to preserve values less than that count.
455+
// E.g., given a count of 6, max value is 5 (binary 0101),
456+
// so we want to return binary 0111.
457+
static uint32_t maskForCount(uint32_t t) {
458+
t -= 1; // Convert count => max value
459+
// Set all bits below highest bit...
460+
t |= t >> 16;
461+
t |= t >> 8;
462+
t |= t >> 4;
463+
t |= t >> 2;
464+
t |= t >> 1;
465+
return t;
466+
}
467+
453468
// Enum with 2 or more non-payload cases and no payload cases
454469
class NoPayloadEnumTypeInfo: public EnumTypeInfo {
455470
public:
@@ -489,6 +504,9 @@ class NoPayloadEnumTypeInfo: public EnumTypeInfo {
489504
if (!reader.readInteger(address, getSize(), &tag)) {
490505
return false;
491506
}
507+
// Strip bits that might be used by a containing MPE:
508+
uint32_t mask = maskForCount(getNumCases());
509+
tag &= mask;
492510
if (tag < getNumCases()) {
493511
*CaseIndex = tag;
494512
return true;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -lswiftSwiftReflectionTest %s -o %t/reflect_Enum_values4
3+
// RUN: %target-codesign %t/reflect_Enum_values4
4+
5+
// RUN: %target-run %target-swift-reflection-test %t/reflect_Enum_values4 | tee /dev/stderr | %FileCheck %s --check-prefix=CHECK%target-ptrsize --check-prefix=CHECKALL --dump-input=fail %add_num_extra_inhabitants
6+
7+
// REQUIRES: objc_interop
8+
// REQUIRES: executable_test
9+
// UNSUPPORTED: use_os_stdlib
10+
11+
import SwiftReflectionTest
12+
13+
enum NonPayloadEnum {
14+
case one
15+
case two
16+
}
17+
18+
enum SmallMultipayloadEnum {
19+
case empty
20+
case a(NonPayloadEnum)
21+
case b(NonPayloadEnum)
22+
}
23+
24+
reflect(enumValue: SmallMultipayloadEnum.b(.two))
25+
26+
// CHECKALL: Reflecting an enum value.
27+
// CHECKALL-NEXT: Type reference:
28+
// CHECKALL-NEXT: (enum reflect_Enum_values4.SmallMultipayloadEnum)
29+
// CHECKALL-NEXT: Value: .b(.two)
30+
31+
reflect(enumValue: SmallMultipayloadEnum.empty)
32+
33+
// CHECKALL: Reflecting an enum value.
34+
// CHECKALL-NEXT: Type reference:
35+
// CHECKALL-NEXT: (enum reflect_Enum_values4.SmallMultipayloadEnum)
36+
// CHECKALL-NEXT: Value: .empty
37+
38+
reflect(enumValue: SmallMultipayloadEnum.a(.one))
39+
40+
// CHECKALL: Reflecting an enum value.
41+
// CHECKALL-NEXT: Type reference:
42+
// CHECKALL-NEXT: (enum reflect_Enum_values4.SmallMultipayloadEnum)
43+
// CHECKALL-NEXT: Value: .a(.one)
44+
45+
46+
doneReflecting()
47+
48+
// CHECKALL: Done.
49+

0 commit comments

Comments
 (0)