Skip to content

Commit

Permalink
[SILGen] Fix a bug where the wrong convention was being used for comp…
Browse files Browse the repository at this point in the history
…uting the type of a closure thunk (#73299)

The ObjC selector family convention was being used instead of the C
function type convention.

rdar://127090209
(cherry picked from commit 428fe21)
  • Loading branch information
ahatanaka committed Apr 30, 2024
1 parent 763421c commit 7b95511
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
13 changes: 13 additions & 0 deletions lib/SIL/IR/SILFunctionType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4069,6 +4069,19 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant(
}
}

// The type of the native-to-foreign thunk for a swift closure.
if (constant.isForeign && constant.hasClosureExpr() &&
shouldStoreClangType(TC.getDeclRefRepresentation(constant))) {
auto clangType = TC.Context.getClangFunctionType(
origLoweredInterfaceType->getParams(),
origLoweredInterfaceType->getResult(),
FunctionTypeRepresentation::CFunctionPointer);
AbstractionPattern pattern =
AbstractionPattern(origLoweredInterfaceType, clangType);
return getSILFunctionTypeForAbstractCFunction(
TC, pattern, origLoweredInterfaceType, extInfoBuilder, constant);
}

// If the decl belongs to an ObjC method family, use that family's
// ownership conventions.
return getSILFunctionTypeForObjCSelectorFamily(
Expand Down
8 changes: 8 additions & 0 deletions test/Interop/Cxx/class/Inputs/closure.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,12 @@ void cfunc2(void (*fp)(NonTrivial)) {
(*fp)(NonTrivial());
}

#if __OBJC__
struct ARCStrong {
id a;
};

void cfuncARCStrong(void (*_Nonnull)(ARCStrong));
#endif

#endif // __CLOSURE__
22 changes: 22 additions & 0 deletions test/Interop/Cxx/class/closure-thunk-macosx.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %target-swiftxx-frontend -I %S/Inputs -emit-silgen %s | %FileCheck %s

// REQUIRES: OS=macosx

import Closure

// CHECK: sil [ossa] @$s4main20testClosureToFuncPtryyF : $@convention(thin) () -> () {
// CHECK: %[[V0:.*]] = function_ref @$s4main20testClosureToFuncPtryyFySo9ARCStrongVcfU_To : $@convention(c) (@owned ARCStrong) -> ()
// CHECK: %[[V1:.*]] = function_ref @_Z14cfuncARCStrongPFv9ARCStrongE : $@convention(c) (@convention(c) (@owned ARCStrong) -> ()) -> ()
// CHECK: apply %[[V1]](%[[V0]]) : $@convention(c) (@convention(c) (@owned ARCStrong) -> ()) -> ()

// CHECK: sil private [thunk] [ossa] @$s4main20testClosureToFuncPtryyFySo9ARCStrongVcfU_To : $@convention(c) (@owned ARCStrong) -> () {
// CHECK: bb0(%[[V0:.*]] : @owned $ARCStrong):
// CHECK: %[[V1:.*]] = begin_borrow %[[V0]] : $ARCStrong
// CHECK: %[[V2:.*]] = function_ref @$s4main20testClosureToFuncPtryyFySo9ARCStrongVcfU_ : $@convention(thin) (@guaranteed ARCStrong) -> ()
// CHECK: apply %[[V2]](%[[V1]]) : $@convention(thin) (@guaranteed ARCStrong) -> ()
// CHECK: end_borrow %[[V1]] : $ARCStrong
// CHECK: destroy_value %[[V0]] : $ARCStrong

public func testClosureToFuncPtr() {
cfuncARCStrong({N in})
}

0 comments on commit 7b95511

Please sign in to comment.