1
- // RUN: %target-sil-opt -closure-lifetime-fixup %s | %FileCheck %s
1
+ // RUN: %target-sil-opt -enable-sil-verify-all - closure-lifetime-fixup %s | %FileCheck %s
2
2
3
3
sil_stage raw
4
4
@@ -7,6 +7,7 @@ import Builtin
7
7
import SwiftShims
8
8
9
9
class FakeNSString {}
10
+ class Klass {}
10
11
11
12
sil @$sSSSgIgg_AAIegg_TR : $@convention(thin) (@guaranteed Optional<String>, @noescape @callee_guaranteed (@guaranteed Optional<String>) -> ()) -> ()
12
13
sil @noescapeBlock3 : $@convention(c) (Optional<@convention(block) @noescape (Optional<FakeNSString>) -> ()>, Optional<@convention(block) @noescape (Optional<FakeNSString>) -> ()>, Optional<FakeNSString>) -> ()
@@ -115,3 +116,42 @@ bb12:
115
116
%77 = enum $Optional<@noescape @callee_guaranteed (@guaranteed Optional<String>) -> ()>, #Optional.none!enumelt
116
117
br bb2(%77 : $Optional<@noescape @callee_guaranteed (@guaranteed Optional<String>) -> ()>)
117
118
}
119
+
120
+ sil @originalClosure : $@convention(thin) () -> ()
121
+ sil @noEscapeThunk : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
122
+ sil @blockThunk : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> ()) -> ()
123
+
124
+ // Just make sure we apply the optimization. The ownership verifier will verify
125
+ // that we do not catch the leak.
126
+ //
127
+ // CHECK-LABEL: sil [ossa] @ssaupdater_no_single_destroy_some_in_exit_block : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed () -> (), @guaranteed Klass, @guaranteed @callee_guaranteed () -> ()) -> () {
128
+ // CHECK-NOT: convert_escape_to_noescape [not_guaranteed]
129
+ // CHECK-NOT: copy_block_without_escaping
130
+ // CHECK: } // end sil function 'ssaupdater_no_single_destroy_some_in_exit_block'
131
+ sil [ossa] @ssaupdater_no_single_destroy_some_in_exit_block : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed () -> (), @guaranteed Klass, @guaranteed @callee_guaranteed () -> ()) -> () {
132
+ bb0(%0 : @guaranteed $Klass, %1 : @guaranteed $@callee_guaranteed () -> (), %2 : @guaranteed $Klass, %3 : @guaranteed $@callee_guaranteed () -> ()):
133
+ // This basic block is needed to trigger the bug.
134
+ br bb1
135
+
136
+ bb1:
137
+ %39 = function_ref @originalClosure : $@convention(thin) () -> ()
138
+ %43 = partial_apply [callee_guaranteed] %39() : $@convention(thin) () -> ()
139
+ %44 = convert_escape_to_noescape [not_guaranteed] %43 : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
140
+ %45 = function_ref @noEscapeThunk : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
141
+ %46 = partial_apply [callee_guaranteed] %45(%44) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
142
+ %47 = mark_dependence %46 : $@callee_guaranteed () -> () on %44 : $@noescape @callee_guaranteed () -> ()
143
+ %48 = copy_value %47 : $@callee_guaranteed () -> ()
144
+ %49 = alloc_stack $@block_storage @callee_guaranteed () -> ()
145
+ %50 = project_block_storage %49 : $*@block_storage @callee_guaranteed () -> ()
146
+ store %48 to [init] %50 : $*@callee_guaranteed () -> ()
147
+ %52 = function_ref @blockThunk : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> ()) -> ()
148
+ %53 = init_block_storage_header %49 : $*@block_storage @callee_guaranteed () -> (), invoke %52 : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> ()) -> (), type $@convention(block) @noescape () -> ()
149
+ %54 = copy_block_without_escaping %53 : $@convention(block) @noescape () -> () withoutEscaping %47 : $@callee_guaranteed () -> ()
150
+ %55 = enum $Optional<@convention(block) @noescape () -> ()>, #Optional.some!enumelt.1, %54 : $@convention(block) @noescape () -> ()
151
+ destroy_addr %50 : $*@callee_guaranteed () -> ()
152
+ dealloc_stack %49 : $*@block_storage @callee_guaranteed () -> ()
153
+ destroy_value %43 : $@callee_guaranteed () -> ()
154
+ destroy_value %55 : $Optional<@convention(block) @noescape () -> ()>
155
+ %86 = tuple ()
156
+ return %86 : $()
157
+ }
0 commit comments