1 // This tests that the symmetric transfer at the final suspend point could happen successfully.
2 // Based on https://github.com/llvm/llvm-project/pull/85271#issuecomment-2007554532
3 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -O2 -emit-llvm %s -o - | FileCheck %s
5 #include "Inputs/coroutine.h"
10 bool await_ready() const noexcept
{ return false; }
11 template <typename PromiseType
>
12 std::coroutine_handle
<> await_suspend(std::coroutine_handle
<PromiseType
> h
) noexcept
{
13 return h
.promise().continuation
;
15 void await_resume() noexcept
{}
17 Task
get_return_object() noexcept
{
18 return std::coroutine_handle
<promise_type
>::from_promise(*this);
20 std::suspend_always
initial_suspend() noexcept
{ return {}; }
21 FinalAwaiter
final_suspend() noexcept
{ return {}; }
22 void unhandled_exception() noexcept
{}
23 void return_value(int x
) noexcept
{
26 std::coroutine_handle
<> continuation
;
30 Task(std::coroutine_handle
<promise_type
> handle
) : handle(handle
), stuff(123) {}
33 std::coroutine_handle
<promise_type
> handle
;
34 Awaiter(std::coroutine_handle
<promise_type
> handle
) : handle(handle
) {}
35 bool await_ready() const noexcept
{ return false; }
36 std::coroutine_handle
<void> await_suspend(std::coroutine_handle
<void> continuation
) noexcept
{
37 handle
.promise().continuation
= continuation
;
40 int await_resume() noexcept
{
41 int ret
= handle
.promise()._value
;
47 auto operator co_await() {
48 auto handle_
= handle
;
50 return Awaiter(handle_
);
54 std::coroutine_handle
<promise_type
> handle
;
62 // CHECK-LABEL: define{{.*}} void @_Z5task0v.resume
63 // This checks we are still in the scope of the current function.
65 // CHECK: musttail call fastcc void
66 // CHECK-NEXT: ret void