Skip to content

Commit bf50e2f

Browse files
Merge pull request #70729 from nate-chandler/rdar119732084
[SILGen] Fix leak in thunk for async throwing swift conformance to ObjC requirement with optional completion.
2 parents 2993e3b + 9f5a7c8 commit bf50e2f

File tree

4 files changed

+77
-2
lines changed

4 files changed

+77
-2
lines changed

lib/SILGen/SILGenBridging.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,10 +1781,10 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
17811781
SILParameterInfo param) {
17821782
auto bridgedTy = param.getInterfaceType();
17831783
auto bridgedArg = emitNativeToBridgedValue(loc,
1784-
arg, nativeFormalTy,
1784+
arg.borrow(*this, loc), nativeFormalTy,
17851785
bridgedTy,
17861786
SILType::getPrimitiveObjectType(bridgedTy));
1787-
completionHandlerArgs.push_back(bridgedArg.borrow(*this, loc).getValue());
1787+
completionHandlerArgs.push_back(bridgedArg.getValue());
17881788
};
17891789

17901790
Scope completionArgDestructureScope(*this, loc);

test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ typedef void (^NonsendableCompletionHandler)(NSString * _Nullable, NSString * _N
8282
-(void)doSomethingSlowNullably:(NSString *)operation completionHandler:(void (^ _Nullable)(NSInteger))handler;
8383
-(void)findAnswerNullably:(NSString *)operation completionHandler:(void (^ _Nullable)(NSString *))handler;
8484
-(void)doSomethingDangerousNullably:(NSString *)operation completionHandler:(void (^ _Nullable)(NSString *_Nullable, NSError *_Nullable))handler;
85+
-(void)doSomethingUnspecifiedNullablyWithCompletionHandler:(void (^ _Nullable)(NSString *_Nullable, NSError *_Nullable))handler;
8586

8687
// rdar://72604599
8788
- (void)stopRecordingWithHandler:(nullable void (^)(NSObject *_Nullable_result x, NSError *_Nullable error))handler __attribute__((swift_async_name("stopRecording()"))) __attribute__((swift_async(not_swift_private, 1)));

test/SILGen/objc_async_from_swift.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ class SlowServerlet: SlowServer {
127127
return x
128128
}
129129

130+
// CHECK-LABEL: sil{{.*}}13SlowServerlet{{.*}}30doSomethingUnspecifiedNullably{{.*}} :
131+
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
132+
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
133+
override func doSomethingUnspecifiedNullably() async throws -> String {
134+
fatalError()
135+
}
136+
130137
// CHECK-LABEL: sil{{.*}}13SlowServerlet{{.*}}17doSomethingFlaggy{{.*}} :
131138
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
132139
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: %target-swift-emit-silgen -module-name Conformance -I %t %t/Conformance.swift -disable-availability-checking | %FileCheck %s
4+
5+
// REQUIRES: concurrency
6+
// REQUIRES: objc_interop
7+
8+
//--- module.modulemap
9+
module ObjCProto {
10+
header "objc_proto.h"
11+
export *
12+
}
13+
14+
//--- objc_proto.h
15+
#import <Foundation/Foundation.h>
16+
17+
@protocol Doable <NSObject>
18+
19+
- (void)doitWithCompletion:(void (^ __nullable)(NSObject * __nullable result, NSError * __nullable error))completion;
20+
21+
@end
22+
23+
//--- Conformance.swift
24+
import ObjCProto
25+
26+
public final class ConformsToProto: NSObject {}
27+
28+
extension ConformsToProto: Doable {
29+
// CHECK-LABEL: sil shared [thunk] [ossa] @$s11Conformance15ConformsToProtoC4doitSo8NSObjectCyYaKFyyYacfU_To : {{.*}} {
30+
// CHECK: {{bb[0-9]+}}([[UNOWNED_MAYBE_COMPLETION:%[^,]+]] :
31+
// CHECK: [[MAYBE_COMPLETION:%[^,]+]] = copy_block [[UNOWNED_MAYBE_COMPLETION]]
32+
// CHECK: try_apply {{.*}} normal [[SUCCESS:bb[0-9]+]], error [[FAILURE:bb[0-9]+]]
33+
// CHECK: [[SUCCESS]]([[RESULT:%[^,]+]] :
34+
// CHECK: [[GUARANTEED_MAYBE_COMPLETION_SUCCESS:%[^,]+]] = begin_borrow [[MAYBE_COMPLETION]]
35+
// CHECK: switch_enum [[GUARANTEED_MAYBE_COMPLETION_SUCCESS]]
36+
// CHECK-SAME: case #Optional.some!enumelt: [[SUCCESS_AND_COMPLETION:bb[0-9]+]]
37+
// CHECK-SAME: case #Optional.none!enumelt: [[SUCCESS_NO_COMPLETION:bb[0-9]+]]
38+
// CHECK: [[SUCCESS_NO_COMPLETION]]:
39+
// CHECK: br [[SUCCESS_JOIN:bb[0-9]+]]
40+
// CHECK: [[SUCCESS_AND_COMPLETION]]
41+
// CHECK: br [[SUCCESS_JOIN]]
42+
// CHECK: [[SUCCESS_JOIN]]:
43+
// CHECK: end_borrow [[GUARANTEED_MAYBE_COMPLETION_SUCCESS]]
44+
// CHECK: destroy_value [[MAYBE_COMPLETION]]
45+
// CHECK: destroy_value [[RESULT]]
46+
// CHECK: br [[EXIT:bb[0-9]+]]
47+
// CHECK: [[FAILURE]]([[ERROR:%[^,]+]] :
48+
// CHECK: [[GUARANTEED_MAYBE_COMPLETION_FAILURE:%[^,]+]] = begin_borrow [[MAYBE_COMPLETION]]
49+
// CHECK: switch_enum [[GUARANTEED_MAYBE_COMPLETION_FAILURE]]
50+
// CHECK-SAME: case #Optional.some!enumelt: [[FAILURE_AND_COMPLETION:bb[0-9]+]]
51+
// CHECK-SAME: case #Optional.none!enumelt: [[FAILURE_NO_COMPLETION:bb[0-9]+]]
52+
// CHECK: [[FAILURE_NO_COMPLETION]]:
53+
// CHECK: br [[FAILURE_JOIN:bb[0-9]+]]
54+
// CHECK: [[FAILURE_AND_COMPLETION]]
55+
// CHECK: br [[FAILURE_JOIN]]
56+
// CHECK: [[FAILURE_JOIN]]:
57+
// CHECK: end_borrow [[GUARANTEED_MAYBE_COMPLETION_FAILURE]]
58+
// CHECK: destroy_value [[MAYBE_COMPLETION]]
59+
// CHECK: destroy_value [[ERROR]]
60+
// CHECK: br [[EXIT]]
61+
// CHECK: [[EXIT]]:
62+
// CHECK-LABEL: } // end sil function '$s11Conformance15ConformsToProtoC4doitSo8NSObjectCyYaKFyyYacfU_To'
63+
public func doit() async throws -> NSObject {
64+
fatalError()
65+
}
66+
}
67+

0 commit comments

Comments
 (0)