Skip to content

Commit e9ebc7c

Browse files
committed
Pass a zero normal result to ObjC async completion handlers on the error path.
Fixes swiftlang#65199
1 parent 3fe7096 commit e9ebc7c

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

lib/SILGen/SILGenBridging.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1985,8 +1985,9 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
19851985
auto param = completionTy->getParameters()[i];
19861986
auto paramTy = param.getSILStorageInterfaceType();
19871987
if (paramTy.isTrivial(F)) {
1988-
// If it's trivial, the value passed doesn't matter.
1989-
completionHandlerArgs.push_back(SILUndef::get(&F, paramTy));
1988+
// If it's trivial, pass a zero value of whatever the type is.
1989+
auto zero = B.createZeroInitValue(loc, paramTy);
1990+
completionHandlerArgs.push_back(zero);
19901991
} else {
19911992
// If it's not trivial, it must be a nullable class type. Pass
19921993
// nil.

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

+4
Original file line numberDiff line numberDiff line change
@@ -364,4 +364,8 @@ MAIN_ACTOR
364364
- (void)loadFloatWithCompletionHandler:(void (^)(float))completionHandler;
365365
@end
366366

367+
@protocol FailableFloatLoader
368+
- (void)loadFloatOrThrowWithCompletionHandler:(void (^)(float, NSError* __nullable)) completionHandler;
369+
@end
370+
367371
#pragma clang assume_nonnull end

test/SILGen/objc_async.swift

+30
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,33 @@ extension OptionalMemberLookups {
330330
func checkHotdogs(_ v: some HotdogCompetitor, _ timeLimit: NSObject) async throws -> String? {
331331
return try await v.pileOfHotdogsToEat(withLimit: timeLimit)
332332
}
333+
334+
/// Issue 65199: pass zero-initialized completion handler arguments for the
335+
/// normal result on the error path of an ObjC async thunk.
336+
extension SlowServer: @retroactive FailableFloatLoader {
337+
public func loadFloatOrThrow() async throws -> Float {
338+
return 0
339+
}
340+
}
341+
// CHECK-LABEL: sil [ossa] @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKF : $@convention(method) @async (@guaranteed SlowServer) -> (Float, @error any Error)
342+
343+
// CHECK-LABEL: sil private [thunk] [ossa] @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKFTo : $@convention(objc_method) (@convention(block) @Sendable (Float, Optional<NSError>) -> (), SlowServer) -> () {
344+
// CHECK: function_ref @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKFyyYacfU_To
345+
346+
// CHECK-LABEL: sil shared [thunk] [ossa] @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKFyyYacfU_To : $@convention(thin) @Sendable @async (@convention(block) @Sendable (Float, Optional<NSError>) -> (), SlowServer) -> ()
347+
// CHECK: [[BLOCK:%.*]] = copy_block
348+
// CHECK: [[METHOD:%.*]] = function_ref @$sSo10SlowServerC10objc_asyncE16loadFloatOrThrowSfyYaKF :
349+
// CHECK: try_apply [[METHOD]]({{%.*}}) : {{.*}}, normal bb1, error bb2
350+
// CHECK: bb1([[NORMAL_RESULT:%.*]] : $Float):
351+
// CHECK-NEXT: [[BORROWED_BLOCK:%.*]] = begin_borrow [[BLOCK]] :
352+
// CHECK-NEXT: [[NIL_NSERROR:%.*]] = enum $Optional<NSError>, #Optional.none
353+
// CHECK-NEXT: apply [[BORROWED_BLOCK]]([[NORMAL_RESULT]], [[NIL_NSERROR]])
354+
// CHECK: bb2([[ERROR_RESULT:%.*]] : @owned $any Error):
355+
// CHECK-NEXT: [[BORROWED_BLOCK:%.*]] = begin_borrow [[BLOCK]] :
356+
// CHECK-NEXT: // function_ref
357+
// CHECK-NEXT: [[CONVERT_FN:%.*]] = function_ref
358+
// CHECK-NEXT: [[NSERROR:%.*]] = apply [[CONVERT_FN]]([[ERROR_RESULT]])
359+
// CHECK-NEXT: [[SOME_NSERROR:%.*]] = enum $Optional<NSError>, #Optional.some!enumelt, [[NSERROR]] : $NSError
360+
// CHECK-NEXT: [[ZERO_FLOAT:%.*]] = builtin "zeroInitializer"() : $Float
361+
// CHECK-NEXT: [[BORROWED_SOME_NSERROR:%.*]] = begin_borrow [[SOME_NSERROR]] :
362+
// CHECK-NEXT: apply [[BORROWED_BLOCK]]([[ZERO_FLOAT]], [[BORROWED_SOME_NSERROR]])

0 commit comments

Comments
 (0)