xref: /llvm-project/clang/test/CodeGenCoroutines/coro-only-destroy-when-complete.cpp (revision b7b5907b56e98719b1dba8364ebcfb264fc09bfe)
1*b7b5907bSChuanqi Xu // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \
2*b7b5907bSChuanqi Xu // RUN:     -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
3*b7b5907bSChuanqi Xu 
4*b7b5907bSChuanqi Xu // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \
5*b7b5907bSChuanqi Xu // RUN:     -O3 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-O
6*b7b5907bSChuanqi Xu 
7*b7b5907bSChuanqi Xu #include "Inputs/coroutine.h"
8*b7b5907bSChuanqi Xu 
9*b7b5907bSChuanqi Xu using namespace std;
10*b7b5907bSChuanqi Xu 
11*b7b5907bSChuanqi Xu struct A;
12*b7b5907bSChuanqi Xu struct A_promise_type {
13*b7b5907bSChuanqi Xu   A get_return_object();
14*b7b5907bSChuanqi Xu   suspend_always initial_suspend();
15*b7b5907bSChuanqi Xu   suspend_always final_suspend() noexcept;
16*b7b5907bSChuanqi Xu   void return_value(int);
17*b7b5907bSChuanqi Xu   void unhandled_exception();
18*b7b5907bSChuanqi Xu 
19*b7b5907bSChuanqi Xu   std::coroutine_handle<> handle;
20*b7b5907bSChuanqi Xu };
21*b7b5907bSChuanqi Xu 
22*b7b5907bSChuanqi Xu struct Awaitable{
23*b7b5907bSChuanqi Xu   bool await_ready();
24*b7b5907bSChuanqi Xu   int await_resume();
25*b7b5907bSChuanqi Xu   template <typename F>
26*b7b5907bSChuanqi Xu   void await_suspend(F);
27*b7b5907bSChuanqi Xu };
28*b7b5907bSChuanqi Xu Awaitable something();
29*b7b5907bSChuanqi Xu 
30*b7b5907bSChuanqi Xu struct dtor {
31*b7b5907bSChuanqi Xu     dtor();
32*b7b5907bSChuanqi Xu     ~dtor();
33*b7b5907bSChuanqi Xu };
34*b7b5907bSChuanqi Xu 
35*b7b5907bSChuanqi Xu struct [[clang::coro_only_destroy_when_complete]] A {
36*b7b5907bSChuanqi Xu   using promise_type = A_promise_type;
37*b7b5907bSChuanqi Xu   A();
38*b7b5907bSChuanqi Xu   A(std::coroutine_handle<>);
39*b7b5907bSChuanqi Xu   ~A();
40*b7b5907bSChuanqi Xu 
41*b7b5907bSChuanqi Xu   std::coroutine_handle<promise_type> handle;
42*b7b5907bSChuanqi Xu };
43*b7b5907bSChuanqi Xu 
foo()44*b7b5907bSChuanqi Xu A foo() {
45*b7b5907bSChuanqi Xu     dtor d;
46*b7b5907bSChuanqi Xu     co_await something();
47*b7b5907bSChuanqi Xu     dtor d1;
48*b7b5907bSChuanqi Xu     co_await something();
49*b7b5907bSChuanqi Xu     dtor d2;
50*b7b5907bSChuanqi Xu     co_return 43;
51*b7b5907bSChuanqi Xu }
52*b7b5907bSChuanqi Xu 
53*b7b5907bSChuanqi Xu // CHECK: define{{.*}}@_Z3foov({{.*}}) #[[ATTR_NUM:[0-9]+]]
54*b7b5907bSChuanqi Xu // CHECK: attributes #[[ATTR_NUM]] = {{.*}}coro_only_destroy_when_complete
55*b7b5907bSChuanqi Xu 
56*b7b5907bSChuanqi Xu // CHECK-O: define{{.*}}@_Z3foov.destroy
57*b7b5907bSChuanqi Xu // CHECK-O: {{^.*}}:
58*b7b5907bSChuanqi Xu // CHECK-O-NOT: br
59*b7b5907bSChuanqi Xu // CHECK-O: ret void
60