[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGenCoroutines / coro-destructor-of-final_suspend.cpp
blobbbc16a196d305eda9699fdc1d107593a80aebf88
1 // This addresses https://github.com/llvm/llvm-project/issues/57339
2 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fcxx-exceptions \
3 // RUN: -fexceptions -emit-llvm -o - %s -O1 | FileCheck %s
5 #include "Inputs/coroutine.h"
7 struct gen {
8 struct promise_type {
9 gen get_return_object() noexcept {
10 return gen{std::coroutine_handle<promise_type>::from_promise(*this)};
12 std::suspend_always initial_suspend() noexcept { return {}; }
14 struct final_awaiter {
15 ~final_awaiter() noexcept;
16 bool await_ready() noexcept {
17 return false;
19 void await_suspend(std::coroutine_handle<>) noexcept {}
20 void await_resume() noexcept {}
23 final_awaiter final_suspend() noexcept {
24 return {};
27 void unhandled_exception() {
28 throw;
30 void return_void() {}
33 gen(std::coroutine_handle<promise_type> coro) noexcept
34 : coro(coro)
38 ~gen() noexcept {
39 if (coro) {
40 coro.destroy();
44 gen(gen&& g) noexcept
45 : coro(g.coro)
47 g.coro = {};
50 std::coroutine_handle<promise_type> coro;
53 struct X {};
55 gen maybe_throwing(bool x) {
56 if (x) {
57 throw X{};
59 co_return;
62 // CHECK: define{{.*}}@_Z14maybe_throwingb.destroy
63 // CHECK: %[[INDEX:.+]] = load i1, ptr %index.addr, align 1
64 // CHECK: br i1 %[[INDEX]], label %[[AFTERSUSPEND:.+]], label %[[CORO_FREE:.+]]
65 // CHECK: [[AFTERSUSPEND]]:
66 // CHECK: call{{.*}}_ZN3gen12promise_type13final_awaiterD1Ev(
67 // CHECK: [[CORO_FREE]]:
68 // CHECK: call{{.*}}_ZdlPv
70 void noexcept_call() noexcept;
72 gen no_throwing() {
73 noexcept_call();
74 co_return;
77 // CHECK: define{{.*}}@_Z11no_throwingv.resume({{.*}}%[[ARG:.+]])
78 // CHECK: resume:
79 // CHECK: call{{.*}}@_Z13noexcept_callv()
80 // CHECK: store ptr null, ptr %[[ARG]]
81 // CHECK: ret void
83 // CHECK: define{{.*}}@_Z11no_throwingv.destroy({{.*}}%[[ARG:.+]])
84 // CHECK: %[[RESUME_FN_ADDR:.+]] = load ptr, ptr %[[ARG]]
85 // CHECK: %[[IF_NULL:.+]] = icmp eq ptr %[[RESUME_FN_ADDR]], null
86 // CHECK: br i1 %[[IF_NULL]], label %[[AFTERSUSPEND:.+]], label %[[CORO_FREE:.+]]
87 // CHECK: [[AFTERSUSPEND]]:
88 // CHECK: call{{.*}}_ZN3gen12promise_type13final_awaiterD1Ev(
89 // CHECK: [[CORO_FREE]]:
90 // CHECK: call{{.*}}_ZdlPv