Skip to content

Commit 6239d7f

Browse files
Merge pull request #17590 from aschwaighofer/irgen_private_resilient_enum_fix_4.2
[4.2] IRGen: Fix multi-payload enum lowering
2 parents d13d600 + 116787d commit 6239d7f

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4115,6 +4115,9 @@ IRGenModule::getResilienceExpansionForAccess(NominalTypeDecl *decl) {
41154115
// layout. Calling isResilient() with this scope will always return false.
41164116
ResilienceExpansion
41174117
IRGenModule::getResilienceExpansionForLayout(NominalTypeDecl *decl) {
4118+
if (Types.isCompletelyFragile())
4119+
return ResilienceExpansion::Minimal;
4120+
41184121
if (isResilient(decl, ResilienceExpansion::Minimal))
41194122
return ResilienceExpansion::Maximal;
41204123

test/IRGen/enum_resilience_objc.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
3+
// RUN: %target-swift-frontend -module-name enum_resilience -I %t -emit-ir -enable-resilience %s | %FileCheck %s -DINT=i%target-ptrsize
4+
// RUN: %target-swift-frontend -module-name enum_resilience -I %t -emit-ir -enable-resilience -O %s
5+
6+
// REQUIRES: objc_interop
7+
8+
// Because the enum is resilient we cannot pack the tag into the pointer inside of the resilient payload.
9+
// CHECK: %T15enum_resilience9ContainerC5Multi33_{{.*}}LLO.0 = type <{ [{{(8|4)}} x i8], [1 x i8] }>
10+
11+
import resilient_struct
12+
13+
public class Container {
14+
private enum Multi {
15+
case none
16+
case some(Container)
17+
case data(ResilientRef)
18+
}
19+
private var e: Multi
20+
var i: Int
21+
init() {
22+
e = .none
23+
i = 0
24+
}
25+
}

test/Inputs/resilient_struct.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,17 @@ public struct ResilientDouble {
7777
self.d = d
7878
}
7979
}
80+
81+
public class Referent {}
82+
83+
public struct ResilientWeakRef {
84+
public weak var ref: Referent?
85+
86+
public init (_ r: Referent) {
87+
ref = r
88+
}
89+
}
90+
91+
public struct ResilientRef {
92+
public var r: Referent
93+
}

test/Interpreter/enum_resilience.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,4 +436,28 @@ ResilientEnumTestSuite.test("ResilientEnumExtension") {
436436
expectEqual(Base.self, ResilientMultiPayloadGenericEnumFixedSize<Base>.A.getTypeParameter())
437437
}
438438

439+
public class Container {
440+
private enum Multi {
441+
case none
442+
case some(Container)
443+
case other(ResilientRef)
444+
}
445+
private var m: Multi
446+
var i: Int
447+
init() {
448+
m = .none
449+
i = 0
450+
switch self.m {
451+
case .none:
452+
print("success")
453+
case .some(_), .other(_):
454+
assert(false, "noooo!")
455+
}
456+
}
457+
}
458+
459+
ResilientEnumTestSuite.test("ResilientPrivateEnumMember") {
460+
_ = Container()
461+
}
462+
439463
runAllTests()

0 commit comments

Comments
 (0)