diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp index b509429ceae8d..558121d1a9b1b 100644 --- a/lib/IRGen/GenEnum.cpp +++ b/lib/IRGen/GenEnum.cpp @@ -1699,7 +1699,7 @@ namespace { projectedBits = IGF.Builder.CreateElementBitCast(projectedBits, IGM.Int8Ty); } extraTag = IGF.Builder.CreateLoad(projectedBits); - auto maskBits = llvm::PowerOf2Ceil(NumExtraTagValues) - 1; + auto maskBits = (1 << ExtraTagBitCount) - 1; auto mask = llvm::ConstantInt::get(extraTag->getType(), maskBits); extraTag = IGF.Builder.CreateAnd(extraTag, mask); } else { diff --git a/test/Interpreter/Inputs/layout_string_witnesses_types.swift b/test/Interpreter/Inputs/layout_string_witnesses_types.swift index d078dec5289a5..b481f76dbb24f 100644 --- a/test/Interpreter/Inputs/layout_string_witnesses_types.swift +++ b/test/Interpreter/Inputs/layout_string_witnesses_types.swift @@ -629,6 +629,38 @@ public enum TwoPayloadOuter { case y(TwoPayloadInner) } +public enum OneExtraTagValue { + public enum E0 { + case a(Bool) + case b(Bool) + } + + public enum E1 { + case a(E0) + case b(Bool) + } + public enum E2 { + case a(E1) + case b(Bool) + } + public enum E3 { + case a(E2) + case b(Bool) + } + + public enum E4 { + case a(E3) + case b(Bool) + } + + case x0(E4, Int8, Int16, Int32) + case x1(E4, Int8, Int16, Int32) + case x2(E4, Int8, Int16, Int32) + case x3(E4, Int8, Int16, Int32) + case y(SimpleClass) + case z +} + @inline(never) public func consume(_ x: T.Type) { withExtendedLifetime(x) {} diff --git a/test/Interpreter/layout_string_witnesses_static.swift b/test/Interpreter/layout_string_witnesses_static.swift index 5ea80f2908387..3f1d728b9103c 100644 --- a/test/Interpreter/layout_string_witnesses_static.swift +++ b/test/Interpreter/layout_string_witnesses_static.swift @@ -1319,6 +1319,35 @@ func testNestedTwoPayload() { testNestedTwoPayload() +func testMultiPayloadOneExtraTagValue() { + let ptr = UnsafeMutablePointer.allocate(capacity: 1) + + do { + let x = OneExtraTagValue.y(SimpleClass(x: 23)) + testInit(ptr, to: x) + } + + do { + let y = OneExtraTagValue.y(SimpleClass(x: 1)) + + // CHECK: Before deinit + print("Before deinit") + + // CHECK-NEXT: SimpleClass deinitialized! + testAssign(ptr, from: y) + } + + // CHECK-NEXT: Before deinit + print("Before deinit") + + // CHECK-NEXT: SimpleClass deinitialized! + testDestroy(ptr) + + ptr.deallocate() +} + +testMultiPayloadOneExtraTagValue() + #if os(macOS) func testObjc() { let ptr = UnsafeMutablePointer.allocate(capacity: 1)