xref: /llvm-project/clang/test/CodeGenCoroutines/pr65018.cpp (revision 6f1b2e4e97e2d6e8f19a9a6d64547b027617fa39)
1 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \
2 // RUN:      -O1 -emit-llvm %s -o - | FileCheck %s
3 
4 #include "Inputs/coroutine.h"
5 
6 // A simple awaiter type with an await_suspend method that can't be
7 // inlined.
8 struct Awaiter {
9   const int& x;
10 
await_readyAwaiter11   bool await_ready() { return false; }
12   std::coroutine_handle<> await_suspend(const std::coroutine_handle<> h);
await_resumeAwaiter13   void await_resume() {}
14 };
15 
16 struct MyTask {
17   // A lazy promise with an await_transform method that supports awaiting
18   // integer references using the Awaiter struct above.
19   struct promise_type {
get_return_objectMyTask::promise_type20     MyTask get_return_object() {
21       return MyTask{
22           std::coroutine_handle<promise_type>::from_promise(*this),
23       };
24     }
25 
initial_suspendMyTask::promise_type26     std::suspend_always initial_suspend() { return {}; }
final_suspendMyTask::promise_type27     std::suspend_always final_suspend() noexcept { return {}; }
28     void unhandled_exception();
29 
await_transformMyTask::promise_type30     auto await_transform(const int& x) { return Awaiter{x}; }
31   };
32 
33   std::coroutine_handle<> h;
34 };
35 
36 // A global array of integers.
37 int g_array[32];
38 
39 // A coroutine that awaits each integer in the global array.
FooBar()40 MyTask FooBar() {
41   for (const int& x : g_array) {
42     co_await x;
43   }
44 }
45 
46 // CHECK: %[[RET:.+]] = {{.*}}call{{.*}}@_ZN7Awaiter13await_suspendESt16coroutine_handleIvE
47 // CHECK: %[[RESUME_ADDR:.+]] = load ptr, ptr %[[RET]],
48 // CHECK: musttail call fastcc void %[[RESUME_ADDR]]({{.*}}%[[RET]]
49 // CHECK: ret
50 
51