[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGenCoroutines / coro-symmetric-transfer-04.cpp
blobcf9170d7e711058475845862c67528310bba2d20
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"
7 struct Task {
8 struct promise_type {
9 struct FinalAwaiter {
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 {
24 _value = x;
26 std::coroutine_handle<> continuation;
27 int _value;
30 Task(std::coroutine_handle<promise_type> handle) : handle(handle), stuff(123) {}
32 struct Awaiter {
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;
38 return handle;
40 int await_resume() noexcept {
41 int ret = handle.promise()._value;
42 handle.destroy();
43 return ret;
47 auto operator co_await() {
48 auto handle_ = handle;
49 handle = nullptr;
50 return Awaiter(handle_);
53 private:
54 std::coroutine_handle<promise_type> handle;
55 int stuff;
58 Task task0() {
59 co_return 43;
62 // CHECK-LABEL: define{{.*}} void @_Z5task0v.resume
63 // This checks we are still in the scope of the current function.
64 // CHECK-NOT: {{^}}}
65 // CHECK: musttail call fastcc void
66 // CHECK-NEXT: ret void