Skip to content

Commit e21c117

Browse files
authored
[cxx-interop] Use unowned return convention for ObjC methods returning foreign reference types (#75640)
This fixes a runtime crash that occurs when a pointer to a foreign reference type is passed to objc_retainAutoreleasedReturnValue. This reverts 335cec0. rdar://117353222
1 parent 8b43ac6 commit e21c117

File tree

3 files changed

+11
-25
lines changed

3 files changed

+11
-25
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include <optional>
4040

4141
#include "CallEmission.h"
42-
#include "ClassTypeInfo.h"
4342
#include "EntryPointArgumentEmission.h"
4443
#include "Explosion.h"
4544
#include "GenCall.h"
@@ -2838,19 +2837,9 @@ class SyncCallEmission final : public CallEmission {
28382837
if (fnConv.getNumDirectSILResults() == 1
28392838
&& (fnConv.getDirectSILResults().begin()->getConvention()
28402839
== ResultConvention::Autoreleased)) {
2841-
if (IGF.IGM.Context.LangOpts.EnableObjCInterop) {
2842-
auto ty = fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext());
2843-
// NOTE: We cannot dyn_cast directly to ClassTypeInfo since it does not
2844-
// implement 'classof', so will succeed for any ReferenceTypeInfo.
2845-
auto *refTypeInfo = dyn_cast<ReferenceTypeInfo>(&IGF.IGM.getTypeInfo(ty));
2846-
if (refTypeInfo &&
2847-
refTypeInfo->getReferenceCountingType() == ReferenceCounting::Custom) {
2848-
Explosion e(result);
2849-
refTypeInfo->as<ClassTypeInfo>().strongCustomRetain(IGF, e, true);
2850-
} else {
2851-
result = emitObjCRetainAutoreleasedReturnValue(IGF, result);
2852-
}
2853-
} else
2840+
if (IGF.IGM.Context.LangOpts.EnableObjCInterop)
2841+
result = emitObjCRetainAutoreleasedReturnValue(IGF, result);
2842+
else
28542843
IGF.emitNativeStrongRetain(result, IGF.getDefaultAtomicity());
28552844
}
28562845

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3381,6 +3381,10 @@ class ObjCMethodConventions : public Conventions {
33813381
// Otherwise, infer based on the method family.
33823382
if (isImplicitPlusOneCFResult())
33833383
return ResultConvention::Owned;
3384+
3385+
if (tl.getLoweredType().isForeignReferenceType())
3386+
return ResultConvention::Unowned;
3387+
33843388
return ResultConvention::Autoreleased;
33853389
}
33863390

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

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,10 @@ import ReferenceCountedObjCProperty
99
// CHECK: %[[LC:.*]] = alloca ptr, align {{4|8}}
1010
// CHECK: %[[V4:.*]] = load ptr, ptr @"\01L_selector(lc)", align {{4|8}}
1111
// CHECK: %[[V5:.*]] = call ptr @objc_msgSend(ptr %{{.*}}, ptr %[[V4]])
12-
// CHECK: %[[V6:.*]] = icmp ne ptr %[[V5]], null
13-
// CHECK: br i1 %[[V6]], label %[[LIFETIME_NONNULL_VALUE:.*]], label %[[LIFETIME_CONT:.*]]
14-
15-
// CHECK: [[LIFETIME_NONNULL_VALUE]]:
16-
// CHECK-NEXT: call void @_Z8LCRetainPN2NS10LocalCountE(ptr %[[V5]])
17-
// CHECK-NEXT: br label %[[LIFETIME_CONT]]
18-
19-
// CHECK: [[LIFETIME_CONT]]:
20-
// CHECK: store ptr %[[V5]], ptr %[[LC]], align {{4|8}}
21-
// CHECK: %[[TODESTROY:.*]] = load ptr, ptr %[[LC]], align {{4|8}}
22-
// CHECK: call void @_Z9LCReleasePN2NS10LocalCountE(ptr %[[TODESTROY]])
12+
// CHECK: call void @_Z8LCRetainPN2NS10LocalCountE(ptr %[[V5]])
13+
// CHECK: store ptr %[[V5]], ptr %[[LC]], align 8
14+
// CHECK: %[[TODESTROY:.*]] = load ptr, ptr %[[LC]], align 8
15+
// CHECK: call void @_Z9LCReleasePN2NS10LocalCountE(ptr %[[TODESTROY]]
2316

2417
public func testGetter() {
2518
var c0 = C0()

0 commit comments

Comments
 (0)