Skip to content

Commit f9e28af

Browse files
committed
When building a block-to-func reabstraction thunk, be sure to bridge
the block's formal parameter and result types, because otherwise the bridging code gets real confused. Fixes rdar://35402696
1 parent 00e71a1 commit f9e28af

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

lib/SILGen/SILGenBridging.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,12 @@ expandTupleTypes(AnyFunctionType::CanParamArrayRef params) {
355355
return results;
356356
}
357357

358+
static CanAnyFunctionType getBridgedBlockType(SILGenModule &SGM,
359+
CanAnyFunctionType blockType) {
360+
return SGM.Types.getBridgedFunctionType(AbstractionPattern(blockType),
361+
blockType, blockType->getExtInfo());
362+
}
363+
358364
static void buildFuncToBlockInvokeBody(SILGenFunction &SGF,
359365
SILLocation loc,
360366
CanAnyFunctionType formalFuncType,
@@ -368,10 +374,7 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &SGF,
368374
SILFunctionConventions funcConv(funcTy, SGF.SGM.M);
369375

370376
// Make sure we lower the component types of the formal block type.
371-
formalBlockType =
372-
SGF.SGM.Types.getBridgedFunctionType(AbstractionPattern(formalBlockType),
373-
formalBlockType,
374-
formalBlockType->getExtInfo());
377+
formalBlockType = getBridgedBlockType(SGF.SGM, formalBlockType);
375378

376379
// Set up the indirect result.
377380
SILType blockResultTy = blockTy->getAllResultsType();
@@ -764,6 +767,9 @@ static void buildBlockToFuncThunkBody(SILGenFunction &SGF,
764767
// Collect the native arguments, which should all be +1.
765768
Scope scope(SGF.Cleanups, CleanupLocation::get(loc));
766769

770+
// Make sure we lower the component types of the formal block type.
771+
formalBlockTy = getBridgedBlockType(SGF.SGM, formalBlockTy);
772+
767773
assert(blockTy->getNumParameters() == funcTy->getNumParameters()
768774
&& "block and function types don't match");
769775

test/SILGen/Inputs/usr/include/BridgeTestFoundation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,5 @@ void escapeBlockAlias(dispatch_block_t block);
9393
@interface ObjectWithSplitProperty : NSObject
9494
@property (nonatomic, setter=private_setFlagForSomething:) BOOL flagForSomething;
9595
@end
96+
97+
extern NSString * __nonnull (^ const __nonnull GlobalBlock)(NSString * __nonnull);

test/SILGen/objc_blocks_bridging.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,11 @@ struct GenericStruct<T> {
188188
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T0Ix_Ixx_IyB_IyBy_TR : $@convention(c) (@inout_aliasable @block_storage @noescape @callee_owned (@owned @noescape @callee_owned () -> ()) -> (), @convention(block) @noescape () -> ()) -> ()
189189
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T0IyB_Ix_TR : $@convention(thin) (@owned @convention(block) @noescape () -> ()) -> ()
190190

191+
// rdar://35402696
192+
func takeOptStringFunction(fn: (String) -> String?) {}
193+
func testGlobalBlock() {
194+
takeOptStringFunction(fn: GlobalBlock)
195+
}
196+
// CHECK-LABEL: sil hidden @_T020objc_blocks_bridging15testGlobalBlockyyF
197+
// CHECK: global_addr @GlobalBlock : $*@convention(block) (NSString) -> @autoreleased Optional<NSString>
198+
// CHECK: function_ref @_T0So8NSStringCABSgIeyBya_S2SIexxo_TR : $@convention(thin) (@owned String, @owned @convention(block) (NSString) -> @autoreleased Optional<NSString>) -> @owned String

0 commit comments

Comments
 (0)