File tree Expand file tree Collapse file tree 2 files changed +33
-0
lines changed Expand file tree Collapse file tree 2 files changed +33
-0
lines changed Original file line number Diff line number Diff line change @@ -694,6 +694,19 @@ static bool isSupportedClosure(const SILInstruction *Closure) {
694
694
return false ;
695
695
}
696
696
697
+ // Bail if it's an ObjectiveC block which might _not_ be copied onto the heap, i.e
698
+ // optimized by SimplifyCopyBlock. We can't do this because the optimization inserts
699
+ // retains+releases for captured arguments. That's not possible for stack-allocated blocks.
700
+ // TODO: avoid inserting retains+releases at all for captures of `partial_apply [on_stack]`
701
+ if (ArgTy.is <SILFunctionType>() &&
702
+ ArgTy.getFunctionRepresentation () == SILFunctionTypeRepresentation::Block &&
703
+ // A `copy_block` ensures that the block is copied onto the heap.
704
+ !isa<CopyBlockInst>(Arg) &&
705
+ // SimplifyCopyBlock only works for `partial_apply [on_stack]`.
706
+ PAI->isOnStack ()) {
707
+ return false ;
708
+ }
709
+
697
710
// Only @inout/@inout_aliasable addresses are (currently) supported.
698
711
// If our argument is an object, continue...
699
712
if (ArgTy.isObject ()) {
Original file line number Diff line number Diff line change
1
+ // RUN: %target-swift-frontend -parse-as-library -O %s -emit-sil | %FileCheck %s
2
+
3
+ func callClosure< R> ( _ body: ( ) -> R ) -> R {
4
+ return body ( )
5
+ }
6
+
7
+ // Check that after removing a copy_block, no retains+releases are inserted for the block.
8
+ // CHECK-LABEL: sil {{.*}}@testit :
9
+ // CHECK-NOT: retain
10
+ // CHECK-NOT: release
11
+ // CHECK: } // end sil function 'testit'
12
+ @_cdecl ( " testit " )
13
+ public func testit( _ block: ( _ index: Int ) -> Int ) -> Bool {
14
+ @inline ( never)
15
+ func c( ) -> Bool {
16
+ return block ( 0 ) != 0
17
+ }
18
+
19
+ return callClosure ( c)
20
+ }
You can’t perform that action at this time.
0 commit comments