Skip to content

Commit d224db8

Browse files
authored
Merge pull request #16129 from ChristopherRogers/SR-7263
[SR-7263] Treat APIs returning unmanaged CF types as NS_RETURNS_INNER_POINTER
2 parents 0be00c8 + 6da2b92 commit d224db8

File tree

5 files changed

+63
-1
lines changed

5 files changed

+63
-1
lines changed

lib/SIL/SILFunctionType.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,11 @@ class ObjCMethodConventions : public Conventions {
14561456
if (tl.isTrivial()) {
14571457
if (Method->hasAttr<clang::ObjCReturnsInnerPointerAttr>())
14581458
return ResultConvention::UnownedInnerPointer;
1459+
1460+
auto type = tl.getLoweredType();
1461+
if (type.unwrapOptionalType().getStructOrBoundGenericStruct()
1462+
== type.getASTContext().getUnmanagedDecl())
1463+
return ResultConvention::UnownedInnerPointer;
14591464
return ResultConvention::Unowned;
14601465
}
14611466

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#import <Foundation/Foundation.h>
2+
3+
@interface Foo: NSObject
4+
5+
- (CFTypeRef _Nonnull)bar;
6+
- (CFTypeRef _Nullable)nullabar;
7+
8+
@end
9+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#import "objc_implicit_inner_pointer.h"
2+
3+
@implementation Foo {
4+
CFTypeRef _bar;
5+
}
6+
7+
- (id)init {
8+
_bar = (__bridge_retained CFTypeRef)[@"1234567891" mutableCopy];
9+
return self;
10+
}
11+
12+
- (CFTypeRef)bar {
13+
return _bar;
14+
}
15+
16+
- (CFTypeRef)nullabar {
17+
return _bar;
18+
}
19+
20+
- (void)dealloc {
21+
printf("%s", __FUNCTION__);
22+
23+
if (_bar)
24+
CFRelease(_bar);
25+
}
26+
27+
@end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-clang -fobjc-arc %S/Inputs/objc_implicit_inner_pointer/objc_implicit_inner_pointer.m -c -o %t/objc_implicit_inner_pointer.o
3+
// RUN: %target-build-swift %s -import-objc-header %S/Inputs/objc_implicit_inner_pointer/objc_implicit_inner_pointer.h %t/objc_implicit_inner_pointer.o -o %t/main
4+
// RUN: %target-run %t/main | %FileCheck %s
5+
6+
// REQUIRES: executable_test
7+
// REQUIRES: objc_interop
8+
9+
do {
10+
// The lifetime of Foo() currently gets extended using autorelease.
11+
autoreleasepool {
12+
let x = Foo().bar().takeUnretainedValue()
13+
print(x) // CHECK: 1234567891
14+
} // CHECK: -[Foo dealloc]
15+
16+
autoreleasepool {
17+
let y = Foo().nullabar()!.takeUnretainedValue()
18+
print(y) // CHECK: 1234567891
19+
} // CHECK: -[Foo dealloc]
20+
}
21+

test/SILGen/cf.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func useEmAll(_ model: CCMagnetismModel) {
2929
// CHECK: function_ref @CCRefrigeratorDestroy : $@convention(c) (@owned Optional<CCRefrigerator>) -> ()
3030
CCRefrigeratorDestroy(clone)
3131

32-
// CHECK: objc_method [[ARG]] : $CCMagnetismModel, #CCMagnetismModel.refrigerator!1.foreign : (CCMagnetismModel) -> () -> Unmanaged<CCRefrigerator>?, $@convention(objc_method) (CCMagnetismModel) -> Optional<Unmanaged<CCRefrigerator>>
32+
// CHECK: objc_method [[ARG]] : $CCMagnetismModel, #CCMagnetismModel.refrigerator!1.foreign : (CCMagnetismModel) -> () -> Unmanaged<CCRefrigerator>?, $@convention(objc_method) (CCMagnetismModel) -> @unowned_inner_pointer Optional<Unmanaged<CCRefrigerator>>
3333
let f0 = model.refrigerator()
3434

3535
// CHECK: objc_method [[ARG]] : $CCMagnetismModel, #CCMagnetismModel.getRefrigerator!1.foreign : (CCMagnetismModel) -> () -> CCRefrigerator?, $@convention(objc_method) (CCMagnetismModel) -> @autoreleased Optional<CCRefrigerator>

0 commit comments

Comments
 (0)