1- // RUN: %target-sil-opt -enable-ossa-complete-lifetimes -test-runner -sil-disable-input-verify %s -o /dev/null 2>&1 | %FileCheck %s
1+ // RUN: %target-sil-opt \
2+ // RUN: -test-runner \
3+ // RUN: -enable-ossa-complete-lifetimes \
4+ // RUN: %s \
5+ // RUN: -sil-disable-input-verify \
6+ // RUN: -o /dev/null \
7+ // RUN: 2>&1 | %FileCheck %s
28
39sil_stage raw
410
@@ -11,6 +17,16 @@ public enum FakeOptional<T> {
1117 case some(T)
1218}
1319
20+ sil @swift_asyncLet_finish : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
21+ sil @swift_asyncLet_get : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
22+
23+ protocol Error {}
24+
25+ enum Optional<Wrapped> {
26+ case none
27+ case some(Wrapped)
28+ }
29+
1430// CHECK-LABEL: begin running test 1 of 1 on eagerConsumneOwnedArg: ossa-lifetime-completion with: @argument
1531// CHECK-LABEL: OSSA lifetime completion: %0 = argument of bb0 : $C
1632// CHECK: sil [ossa] @eagerConsumneOwnedArg : $@convention(thin) (@owned C) -> () {
@@ -455,3 +471,30 @@ right:
455471 end_borrow %c : $C
456472 unreachable
457473}
474+
475+ // Nothing to check here--the output is the same as the input. Verify that
476+ // completing the lifetime of a value used by a startAsyncLetWithLocalBuffer
477+ // doesn't crash when visiting an endAsyncLetLifetime.
478+ sil [ossa] @async_let : $@convention(thin) @async () -> () {
479+ bb0:
480+ %result_addr = alloc_stack $()
481+ %result_ptr = address_to_pointer %result_addr : $*() to $Builtin.RawPointer
482+ %task_options = enum $Optional<Builtin.RawPointer>, #Optional.none!enumelt
483+ %callee_pa = partial_apply [callee_guaranteed] undef() : $@convention(thin) @async @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
484+ %callee_noescape = convert_escape_to_noescape [not_guaranteed] %callee_pa : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
485+ to $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
486+ specify_test "ossa-lifetime-completion %callee_noescape"
487+ %async_let = builtin "startAsyncLetWithLocalBuffer"<()>(
488+ %task_options : $Optional<Builtin.RawPointer>,
489+ %callee_noescape : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>,
490+ %result_ptr : $Builtin.RawPointer
491+ ) : $Builtin.RawPointer
492+ %get = function_ref @swift_asyncLet_get : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
493+ apply %get(%async_let, %result_ptr) : $@convention(thin) @async (Builtin.RawPointer, Builtin.RawPointer) -> ()
494+ builtin "endAsyncLetLifetime"(%async_let : $Builtin.RawPointer) : $()
495+ destroy_value %callee_noescape : $@noescape @async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
496+ destroy_value %callee_pa : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
497+ %retval = load [trivial] %result_addr : $*()
498+ dealloc_stack %result_addr : $*()
499+ return %retval : $()
500+ }
0 commit comments