Skip to content

Commit 974a351

Browse files
committed
[cxx-interop] Emit retain/release correctly for FRT's that are stored in optionals and have custom ref counting instructions.
1 parent 485c8cc commit 974a351

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
#include "ScalarTypeInfo.h"
134134
#include "StructLayout.h"
135135
#include "SwitchBuilder.h"
136+
#include "ClassTypeInfo.h"
136137

137138
using namespace swift;
138139
using namespace irgen;
@@ -2467,9 +2468,17 @@ namespace {
24672468
void retainRefcountedPayload(IRGenFunction &IGF,
24682469
llvm::Value *ptr) const {
24692470
switch (CopyDestroyKind) {
2470-
case NullableRefcounted:
2471+
case NullableRefcounted: {
2472+
if (Refcounting == ReferenceCounting::Custom) {
2473+
Explosion e;
2474+
e.add(ptr);
2475+
getPayloadTypeInfo().as<ClassTypeInfo>().strongRetain(IGF, e, IGF.getDefaultAtomicity());
2476+
return;
2477+
}
2478+
24712479
IGF.emitStrongRetain(ptr, Refcounting, IGF.getDefaultAtomicity());
24722480
return;
2481+
}
24732482
case ForwardToPayload:
24742483
case POD:
24752484
case Normal:
@@ -2495,9 +2504,17 @@ namespace {
24952504
void releaseRefcountedPayload(IRGenFunction &IGF,
24962505
llvm::Value *ptr) const {
24972506
switch (CopyDestroyKind) {
2498-
case NullableRefcounted:
2507+
case NullableRefcounted: {
2508+
if (Refcounting == ReferenceCounting::Custom) {
2509+
Explosion e;
2510+
e.add(ptr);
2511+
getPayloadTypeInfo().as<ClassTypeInfo>().strongRelease(IGF, e, IGF.getDefaultAtomicity());
2512+
return;
2513+
}
2514+
24992515
IGF.emitStrongRelease(ptr, Refcounting, IGF.getDefaultAtomicity());
25002516
return;
2517+
}
25012518
case ForwardToPayload:
25022519
case POD:
25032520
case Normal:

test/Interop/Cxx/foreign-reference/reference-counted.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-experimental-cxx-interop -Xfrontend -validate-tbd-against-ir=none -Xfrontend -disable-llvm-verify -g)
1+
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-experimental-cxx-interop -Xfrontend -validate-tbd-against-ir=none -Xfrontend -disable-llvm-verify)
22
//
33
// REQUIRES: executable_test
44
// TODO: This should work without ObjC interop in the future rdar://97497120
55
// REQUIRES: objc_interop
66

7-
// REQUIRES: rdar97532642
7+
// Issues with 32 bit: rdar://97532642
8+
// UNSUPPORTED: CPU=i386
89

910
import StdlibUnittest
1011
import ReferenceCounted
@@ -29,6 +30,14 @@ ReferenceCountedTestSuite.test("Local") {
2930
expectEqual(finalLocalRefCount, 0)
3031
}
3132

33+
var globalOptional: NS.LocalCount? = nil
34+
35+
ReferenceCountedTestSuite.test("Global optional holding local ref count") {
36+
expectEqual(finalLocalRefCount, 0)
37+
globalOptional = NS.LocalCount.create()
38+
expectEqual(finalLocalRefCount, 1)
39+
}
40+
3241
@inline(never)
3342
func globalTest1() {
3443
var x = GlobalCount.create()

0 commit comments

Comments
 (0)