Skip to content

Commit 95e31ee

Browse files
committed
IRGen: Fix multipayload enums with indirect cases
swift_unknownRetain does not work on indirect enum heap buffers. The existing logic would say: oh one case is ReferenceCounting::BridgeObject (which on its own probably would not work with swift_unknownRetain), oh and another second case is NativeObject (for the indirect buffer), let's use unknowRetain. Pair the logic down to only use a single style of reference count operation if all cases are of the same ReferenceCounting type. rdar://40525268
1 parent 9aca727 commit 95e31ee

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3129,15 +3129,12 @@ namespace {
31293129
&refcounting)) {
31303130
allSingleRefcount = false;
31313131
} else if (haveRefcounting) {
3132-
// Different payloads have different reference counting styles.
3133-
if (refcounting != Refcounting) {
3134-
// Fall back to unknown entry points if the Objective-C runtime is
3135-
// available.
3136-
Refcounting = ReferenceCounting::Unknown;
3137-
// Otherwise, use value witnesses.
3138-
if (!IGM.ObjCInterop)
3139-
allSingleRefcount = false;
3140-
}
3132+
// Only support a single style of reference counting for now.
3133+
// swift_unknowRetain does not support the heap buffer of indirect
3134+
// enums. And I am not convinced that unknowRetain supports
3135+
// bridgedObjectRetain.
3136+
if (refcounting != Refcounting)
3137+
allSingleRefcount = false;
31413138
} else {
31423139
Refcounting = refcounting;
31433140
haveRefcounting = true;

test/Interpreter/enum.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,3 +667,33 @@ public func testCase(_ closure: @escaping (Int) -> ()) -> Indirect<(Int) -> ()>
667667

668668
// CHECK: payload((Function), other: (Function))
669669
print(testCase({ _ in }))
670+
671+
672+
enum MultiIndirectRef {
673+
case empty
674+
indirect case ind(Int)
675+
case collection([Int])
676+
}
677+
678+
struct Container {
679+
var storage : MultiIndirectRef = .empty
680+
681+
mutating func adoptStyle(_ s: Int) {
682+
storage = .ind(s)
683+
}
684+
}
685+
686+
func copyStorage(_ s: Int, _ x : Container) -> Container {
687+
var c = x
688+
c.adoptStyle(s)
689+
return c
690+
}
691+
692+
func testCase() {
693+
let l = Container()
694+
let c = copyStorage(5, l)
695+
print(c)
696+
}
697+
698+
// CHECK: Container(storage: a.MultiIndirectRef.ind(5))
699+
testCase()

0 commit comments

Comments
 (0)