File tree Expand file tree Collapse file tree 7 files changed +92
-4
lines changed Expand file tree Collapse file tree 7 files changed +92
-4
lines changed Original file line number Diff line number Diff line change @@ -1869,7 +1869,9 @@ class SelectorFamilyConventions : public Conventions {
1869
1869
break ;
1870
1870
}
1871
1871
1872
- auto type = tl.getLoweredType ().getASTType ();
1872
+ // Get the underlying AST type, potentially stripping off one level of
1873
+ // optionality while we do it.
1874
+ CanType type = tl.getLoweredType ().unwrapOptionalType ().getASTType ();
1873
1875
if (type->hasRetainablePointerRepresentation ()
1874
1876
|| (type->getSwiftNewtypeUnderlyingType () && !tl.isTrivial ()))
1875
1877
return ResultConvention::Autoreleased;
Original file line number Diff line number Diff line change @@ -135,12 +135,16 @@ class ObjCTest {
135
135
// CHECK-LABEL: define hidden %0* @"$s7newtype8ObjCTestC19optionalPassThroughySo14SNTErrorDomainaSgAGFTo"
136
136
// CHECK: [[CASTED:%.+]] = ptrtoint %0* %2 to i{{32|64}}
137
137
// CHECK: [[RESULT:%.+]] = call swiftcc i{{32|64}} @"$s7newtype8ObjCTestC19optionalPassThroughySo14SNTErrorDomainaSgAGF"(i{{32|64}} [[CASTED]], %T7newtype8ObjCTestC* swiftself {{%.+}})
138
- // CHECK: [[OPAQUE_RESULT:%.+]] = inttoptr i{{32|64}} [[RESULT]] to %0*
138
+ // CHECK: [[AUTORELEASE_RESULT:%.+]] = {{(tail )?}}call {{.*}} @objc_autoreleaseReturnValue {{.*}}(i{{32|64}} [[RESULT]])
139
+ // CHECK: [[OPAQUE_RESULT:%.+]] = inttoptr i{{32|64}} [[AUTORELEASE_RESULT]] to %0*
139
140
// CHECK: ret %0* [[OPAQUE_RESULT]]
140
141
// CHECK: {{^}$}}
141
142
142
143
// OPT-LABEL: define hidden %0* @"$s7newtype8ObjCTestC19optionalPassThroughySo14SNTErrorDomainaSgAGFTo"
143
- // OPT: ret %0* %2
144
+ // OPT: [[CAST_VALUE:%.*]] = bitcast %0* %2 to %objc_object*
145
+ // OPT: [[RESULT:%.*]] = {{(tail )?}}call %objc_object* @objc_autoreleaseReturnValue(%objc_object* [[CAST_VALUE]])
146
+ // OPT: [[RESULT_CAST:%.*]] = bitcast %objc_object* [[RESULT]] to %0*
147
+ // OPT: ret %0* [[RESULT_CAST]]
144
148
// OPT: {{^}$}}
145
149
@objc func optionalPassThrough( _ ed: ErrorDomain ? ) -> ErrorDomain ? {
146
150
return ed
Original file line number Diff line number Diff line change
1
+
2
+ #include < stdio.h>
3
+ #include " newtype.h"
4
+
5
+ @implementation NSMyObject
6
+
7
+ @synthesize lifetimeTracked;
8
+
9
+ -(instancetype )init {
10
+ self = [super init ];
11
+ if (!self) {
12
+ return nil ;
13
+ }
14
+ self.lifetimeTracked = nil ;
15
+ return self;
16
+ }
17
+
18
+ - (void )print {
19
+ printf (" I am alive?!\n " );
20
+ fflush (stdout);
21
+ }
22
+
23
+ @end
Original file line number Diff line number Diff line change
1
+ module Newtype {
2
+ header "newtype.h"
3
+ export *
4
+ }
Original file line number Diff line number Diff line change
1
+
2
+ @import ObjectiveC;
3
+
4
+ @interface NSMyObject : NSObject
5
+
6
+ -(NSMyObject *)init ;
7
+ -(void )print ;
8
+
9
+ @property (retain ) id lifetimeTracked;
10
+
11
+ @end
12
+
13
+ typedef NSMyObject *MyObject __attribute ((swift_newtype(struct ))) __attribute((swift_name(" MyObject" )));
Original file line number Diff line number Diff line change
1
+ // RUN: %empty-directory(%t)
2
+ // RUN: %target-clang -c %S/Inputs/newtype.m -o %t/newtype.objc.o -I %S/Inputs/usr/include -fmodules
3
+ // RUN: %target-build-swift -c -I %S/Inputs/usr/include -o %t/newtype.swift.o %s
4
+ // RUN: %swiftc_driver %t/newtype.objc.o %t/newtype.swift.o -o %t/newtype
5
+ // RUN: %target-codesign %t/newtype
6
+ // RUN: %target-run %t/newtype
7
+
8
+ // REQUIRES: executable_test
9
+ // REQUIRES: objc_interop
10
+
11
+ import Foundation
12
+ import StdlibUnittest
13
+ import Newtype
14
+
15
+ class ObjCLifetimeTracked : NSMyObject {
16
+ var a = LifetimeTracked ( 0 )
17
+ }
18
+
19
+ // Make sure that we do properly autorelease newtypes and do not leak them.
20
+ class ObjCTest : NSObject {
21
+ @objc dynamic func optionalPassThrough( _ ed: MyObject ? ) -> MyObject ? {
22
+ return ed
23
+ }
24
+ }
25
+
26
+ func main( ) {
27
+ let e = MyObject ( ObjCLifetimeTracked ( ) )
28
+ let c = ObjCTest ( )
29
+ let x = c. optionalPassThrough ( e) !
30
+ x. rawValue. print ( )
31
+ }
32
+
33
+ var Tests = TestSuite ( " newtypeleak " )
34
+
35
+ Tests . test ( " dontLeak " ) {
36
+ autoreleasepool {
37
+ main ( )
38
+ }
39
+ expectEqual ( 0 , LifetimeTracked . instances)
40
+ }
41
+
42
+ runAllTests ( )
Original file line number Diff line number Diff line change @@ -48,7 +48,7 @@ func getRawValue(ed: ErrorDomain) -> String {
48
48
49
49
class ObjCTest {
50
50
// CHECK-RAW-LABEL: sil hidden @$s7newtype8ObjCTestC19optionalPassThroughySo14SNTErrorDomainaSgAGF : $@convention(method) (@guaranteed Optional<ErrorDomain>, @guaranteed ObjCTest) -> @owned Optional<ErrorDomain> {
51
- // CHECK-RAW: sil hidden [thunk] @$s7newtype8ObjCTestC19optionalPassThroughySo14SNTErrorDomainaSgAGFTo : $@convention(objc_method) (Optional<ErrorDomain>, ObjCTest) -> Optional<ErrorDomain> {
51
+ // CHECK-RAW: sil hidden [thunk] @$s7newtype8ObjCTestC19optionalPassThroughySo14SNTErrorDomainaSgAGFTo : $@convention(objc_method) (Optional<ErrorDomain>, ObjCTest) -> @autoreleased Optional<ErrorDomain> {
52
52
@objc func optionalPassThrough( _ ed: ErrorDomain ? ) -> ErrorDomain ? {
53
53
return ed
54
54
}
You can’t perform that action at this time.
0 commit comments