@@ -6,11 +6,24 @@ import Swift
66
77class NonSendableKlass {}
88
9+ @_moveOnly
10+ struct NonSendableMoveOnlyStruct {
11+ var ns: NonSendableKlass
12+ }
13+
14+ struct NonSendableStruct {
15+ var ns: NonSendableKlass
16+ }
17+
918sil @transferKlass : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
10- sil @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
1119sil @useKlass : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
1220sil @constructKlass : $@convention(thin) () -> @owned NonSendableKlass
1321
22+ sil @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
23+ sil @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
24+
25+ sil @constructMoveOnlyStruct : $@convention(thin) () -> @owned NonSendableMoveOnlyStruct
26+
1427enum FakeOptional<T> {
1528case none
1629case some(T)
@@ -105,3 +118,174 @@ bb0:
105118 %9999 = tuple ()
106119 return %9999 : $()
107120}
121+
122+ sil [ossa] @move_value_test : $@convention(thin) @async () -> () {
123+ bb0:
124+ %0 = function_ref @constructKlass : $@convention(thin) () -> @owned NonSendableKlass
125+ %1 = apply %0() : $@convention(thin) () -> @owned NonSendableKlass
126+ %2 = function_ref @transferKlass : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
127+ %1a = move_value %1 : $NonSendableKlass
128+ apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %2(%1a) : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
129+ // expected-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' from nonisolated context to global actor '<null>'-isolated context at this call site could yield a race with accesses later in this function}}
130+ %3 = function_ref @useKlass : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
131+ apply %3(%1a) : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
132+ // expected-note @-1 {{access here could race}}
133+ destroy_value %1a : $NonSendableKlass
134+ %9999 = tuple ()
135+ return %9999 : $()
136+ }
137+
138+ sil [ossa] @mark_unresolved_noncopyable_value_test : $@convention(thin) @async () -> () {
139+ bb0:
140+ %0 = function_ref @constructMoveOnlyStruct : $@convention(thin) () -> @owned NonSendableMoveOnlyStruct
141+ %1 = apply %0() : $@convention(thin) () -> @owned NonSendableMoveOnlyStruct
142+ %box = alloc_box ${ var NonSendableMoveOnlyStruct }
143+ %project = project_box %box : ${ var NonSendableMoveOnlyStruct }, 0
144+ %unresolved = mark_unresolved_non_copyable_value [consumable_and_assignable] %project : $*NonSendableMoveOnlyStruct
145+ store %1 to [init] %unresolved : $*NonSendableMoveOnlyStruct
146+
147+ %4 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
148+ apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %4<NonSendableMoveOnlyStruct>(%unresolved) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
149+ // expected-warning @-1 {{passing argument of non-sendable type 'NonSendableMoveOnlyStruct' from nonisolated context to global actor '<null>'-isolated context at this call site could yield a race with accesses later in this function}}
150+ %5 = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
151+ apply %5<NonSendableMoveOnlyStruct>(%unresolved) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
152+ // expected-note @-1 {{access here could race}}
153+ destroy_value %box : ${ var NonSendableMoveOnlyStruct }
154+ %9999 = tuple ()
155+ return %9999 : $()
156+ }
157+
158+ sil [ossa] @mark_unresolved_reference_binding_test : $@convention(thin) @async () -> () {
159+ bb0:
160+ %0 = function_ref @constructKlass : $@convention(thin) () -> @owned NonSendableKlass
161+ %1 = apply %0() : $@convention(thin) () -> @owned NonSendableKlass
162+ %box = alloc_box ${ var NonSendableKlass }
163+ %binding = mark_unresolved_reference_binding [inout] %box : ${ var NonSendableKlass }
164+ %project = project_box %binding : ${ var NonSendableKlass }, 0
165+ store %1 to [init] %project : $*NonSendableKlass
166+
167+ %4 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
168+ apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %4<NonSendableKlass>(%project) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
169+ // expected-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' from nonisolated context to global actor '<null>'-isolated context at this call site could yield a race with accesses later in this function}}
170+ %5 = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
171+ apply %5<NonSendableKlass>(%project) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
172+ // expected-note @-1 {{access here could race}}
173+ destroy_value %binding : ${ var NonSendableKlass }
174+ %9999 = tuple ()
175+ return %9999 : $()
176+ }
177+
178+ sil [ossa] @copyable_to_moveonly_wrapper_value_and_back_test : $@convention(thin) @async () -> () {
179+ bb0:
180+ %0 = function_ref @constructKlass : $@convention(thin) () -> @owned NonSendableKlass
181+ %1 = apply %0() : $@convention(thin) () -> @owned NonSendableKlass
182+ %2 = function_ref @transferKlass : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
183+ %0a = copyable_to_moveonlywrapper [owned] %1 : $NonSendableKlass
184+
185+ %0b = begin_borrow %0a : $@moveOnly NonSendableKlass
186+ %0c = moveonlywrapper_to_copyable [guaranteed] %0b : $@moveOnly NonSendableKlass
187+ apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %2(%0c) : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
188+ // expected-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' from nonisolated context to global actor '<null>'-isolated context at this call site could yield a race with accesses later in this function}}
189+ end_borrow %0b : $@moveOnly NonSendableKlass
190+ %3 = function_ref @useKlass : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
191+ %0bb = begin_borrow %0a : $@moveOnly NonSendableKlass
192+ %0d = moveonlywrapper_to_copyable [guaranteed] %0bb : $@moveOnly NonSendableKlass
193+ apply %3(%0d) : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
194+ // expected-note @-1 {{access here could race}}
195+ end_borrow %0bb : $@moveOnly NonSendableKlass
196+ destroy_value %0a : $@moveOnly NonSendableKlass
197+ %9999 = tuple ()
198+ return %9999 : $()
199+ }
200+
201+ sil [ossa] @test_moveonlywrapper_to_copyable_addr : $@convention(thin) @async () -> () {
202+ bb0:
203+ %1 = function_ref @constructKlass : $@convention(thin) () -> @owned NonSendableKlass
204+ %2 = apply %1() : $@convention(thin) () -> @owned NonSendableKlass
205+ %box = alloc_box ${ var @moveOnly NonSendableKlass }
206+ %bb = begin_borrow [var_decl] %box : ${ var @moveOnly NonSendableKlass }
207+ %project = project_box %bb : ${ var @moveOnly NonSendableKlass }, 0
208+ %unwrappedProject = moveonlywrapper_to_copyable_addr %project : $*@moveOnly NonSendableKlass
209+ store %2 to [init] %unwrappedProject : $*NonSendableKlass
210+
211+ %4 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
212+ apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %4<NonSendableKlass>(%unwrappedProject) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
213+ // expected-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' from nonisolated context to global actor '<null>'-isolated context at this call site could yield a race with accesses later in this function}}
214+
215+ %5 = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
216+ apply %5<NonSendableKlass>(%unwrappedProject) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
217+ // expected-note @-1 {{access here could race}}
218+
219+ end_borrow %bb : ${ var @moveOnly NonSendableKlass }
220+ destroy_value %box : ${ var @moveOnly NonSendableKlass }
221+ %9999 = tuple ()
222+ return %9999 : $()
223+ }
224+
225+ sil @partial_apply_box : $@convention(thin) (@guaranteed { var NonSendableKlass }) -> ()
226+ sil @transfer_partial_apply : $@convention(thin) @async (@guaranteed @callee_owned () -> ()) -> ()
227+
228+ sil [ossa] @test_moveonlywrapper_to_copyable_box : $@convention(thin) @async () -> () {
229+ bb0:
230+ %1 = function_ref @constructKlass : $@convention(thin) () -> @owned NonSendableKlass
231+ %2 = apply %1() : $@convention(thin) () -> @owned NonSendableKlass
232+ %box = alloc_box ${ var @moveOnly NonSendableKlass }
233+ %bb = begin_borrow %box : ${ var @moveOnly NonSendableKlass }
234+ %project = project_box %bb : ${ var @moveOnly NonSendableKlass }, 0
235+ %unwrappedProject = moveonlywrapper_to_copyable_addr %project : $*@moveOnly NonSendableKlass
236+ store %2 to [init] %unwrappedProject : $*NonSendableKlass
237+ end_borrow %bb : ${ var @moveOnly NonSendableKlass }
238+
239+ %unwrappedBox = moveonlywrapper_to_copyable_box %box : ${ var @moveOnly NonSendableKlass }
240+
241+ %f2 = function_ref @partial_apply_box : $@convention(thin) (@guaranteed { var NonSendableKlass }) -> ()
242+ %copiedUnwrappedBox = copy_value %unwrappedBox : ${ var NonSendableKlass }
243+ %pa = partial_apply %f2(%copiedUnwrappedBox) : $@convention(thin) (@guaranteed { var NonSendableKlass }) -> ()
244+ %4 = function_ref @transfer_partial_apply : $@convention(thin) @async (@guaranteed @callee_owned () -> ()) -> ()
245+ apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %4(%pa) : $@convention(thin) @async (@guaranteed @callee_owned () -> ()) -> ()
246+ // expected-warning @-1 {{passing argument of non-sendable type '@callee_owned () -> ()' from nonisolated context to global actor '<null>'-isolated context at this call site could yield a race with accesses later in this function}}
247+ %bb2 = begin_borrow %unwrappedBox : ${ var NonSendableKlass }
248+ %p2 = project_box %bb2 : ${ var NonSendableKlass }, 0
249+ %5 = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
250+ apply %5<NonSendableKlass>(%p2) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
251+ // expected-note @-1 {{access here could race}}
252+ end_borrow %bb2 : ${ var NonSendableKlass }
253+
254+ destroy_value %pa : $@callee_owned () -> ()
255+ destroy_value %unwrappedBox : ${ var NonSendableKlass }
256+ %9999 = tuple ()
257+ return %9999 : $()
258+ }
259+
260+ sil [ossa] @mark_uninitialized_test : $@convention(method) @async (@owned NonSendableStruct) -> () {
261+ bb0(%0 : @owned $NonSendableStruct):
262+ %1 = alloc_stack $NonSendableStruct, var, name "self"
263+ %2 = mark_uninitialized [rootself] %1 : $*NonSendableStruct
264+ %7 = begin_access [modify] [static] %2 : $*NonSendableStruct
265+ store %0 to [init] %7 : $*NonSendableStruct
266+ end_access %7 : $*NonSendableStruct
267+
268+ %4 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
269+ apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %4<NonSendableStruct>(%2) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
270+ // expected-warning @-1 {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
271+
272+ %5 = function_ref @useIndirect : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
273+ apply %5<NonSendableStruct>(%2) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
274+
275+ destroy_addr %1 : $*NonSendableStruct
276+ dealloc_stack %1 : $*NonSendableStruct
277+
278+ %9999 = tuple ()
279+ return %9999 : $()
280+ }
281+
282+ sil [ossa] @copyable_to_moveonlywrapper_addr_test : $@convention(thin) @async (@in_guaranteed NonSendableStruct) -> () {
283+ bb0(%0 : $*NonSendableStruct):
284+ %1 = copyable_to_moveonlywrapper_addr %0 : $*NonSendableStruct
285+ %2 = moveonlywrapper_to_copyable_addr %1 : $*@moveOnly NonSendableStruct
286+ %4 = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
287+ apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %4<NonSendableStruct>(%2) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
288+ // expected-warning @-1 {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
289+ %9999 = tuple ()
290+ return %9999 : $()
291+ }
0 commit comments