1 // Test for PR56919. Tests the we won't contain the resumption of final suspend point.
3 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -O3 -emit-llvm -o - | FileCheck %s
4 // This test is expected to fail on PowerPC.
5 // XFAIL: target=powerpc{{.*}}
7 #include "Inputs/coroutine.h"
9 void _exit(int status
) __attribute__ ((__noreturn__
));
13 // An object that can be co_awaited, but we always resume immediately from
15 struct ResumeFromAwaitSuspend
{};
18 using promise_type
= Promise
;
23 static std::coroutine_handle
<Promise
> GetHandle(Promise
& promise
) {
24 return std::coroutine_handle
<Promise
>::from_promise(promise
);
27 void unhandled_exception() {}
28 Task
get_return_object() { return Task
{*this}; }
31 // Always suspend before starting the coroutine body. We actually run the body
32 // when we are co_awaited.
33 std::suspend_always
initial_suspend() { return {}; }
35 // We support awaiting tasks. We do so by configuring them to resume us when
36 // they are finished, and then resuming them from their initial suspend.
37 auto await_transform(Task
&& task
) {
39 bool await_ready() { return false; }
41 std::coroutine_handle
<> await_suspend(
42 const std::coroutine_handle
<> handle
) {
43 // Tell the child to resume the parent once it finishes.
44 child
.resume_at_final_suspend
= GetHandle(parent
);
47 return GetHandle(child
);
51 // The child is now at its final suspend point, and can be destroyed.
52 return GetHandle(child
).destroy();
61 .child
= task
.promise
,
65 // Make evaluation of `co_await ResumeFromAwaitSuspend{}` go through the
66 // await_suspend path, but cause it to resume immediately by returning our own
68 auto await_transform(ResumeFromAwaitSuspend
) {
70 bool await_ready() { return false; }
72 std::coroutine_handle
<> await_suspend(const std::coroutine_handle
<> h
) {
76 void await_resume() {}
82 // Always suspend at the final suspend point, transferring control back to our
83 // caller. We expect never to be resumed from the final suspend.
84 auto final_suspend() noexcept
{
85 struct FinalSuspendAwaitable final
{
86 bool await_ready() noexcept
{ return false; }
88 std::coroutine_handle
<> await_suspend(std::coroutine_handle
<>) noexcept
{
89 return promise
.resume_at_final_suspend
;
92 void await_resume() noexcept
{
99 return FinalSuspendAwaitable
{.promise
= *this};
102 // The handle we will resume once we hit final suspend.
103 std::coroutine_handle
<> resume_at_final_suspend
;
109 co_await
ResumeFromAwaitSuspend();
113 // CHECK: define{{.*}}@_Z5Outerv.resume(
116 // CHECK: musttail call
117 // CHECK: musttail call
118 // CHECK: musttail call
119 // CHECK-NEXT: ret void
121 // CHECK-NEXT: unreachable:
122 // CHECK-NEXT: unreachable