1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11#include <coroutine>
12#include <cassert>
13
14#include "test_macros.h"
15
16int alive = 0;
17int ctor_called = 0;
18int dtor_called = 0;
19void reset() {
20 assert(alive == 0);
21 alive = 0;
22 ctor_called = 0;
23 dtor_called = 0;
24}
25struct Noisy {
26 Noisy() { ++alive; ++ctor_called; }
27 ~Noisy() { --alive; ++dtor_called; }
28 Noisy(Noisy const&) = delete;
29};
30
31struct Bug {
32 bool await_ready() { return true; }
33 void await_suspend(std::coroutine_handle<>) {}
34 Noisy await_resume() { return {}; }
35};
36struct coro2 {
37 struct promise_type {
38 std::suspend_never initial_suspend() { return {}; }
39 std::suspend_never final_suspend() noexcept { return {}; }
40 coro2 get_return_object() { return {}; }
41 void return_void() {}
42 Bug yield_value(int) { return {}; }
43 void unhandled_exception() {}
44 };
45};
46
47// Checks that destructors are correctly invoked for the object returned by
48// coawait.
49coro2 a() {
50 reset();
51 {
52 auto x = co_await Bug{};
53 assert(alive == 1);
54 assert(ctor_called == 1);
55 assert(dtor_called == 0);
56 ((void)x);
57 }
58 assert(alive == 0);
59 assert(dtor_called == 1);
60}
61
62coro2 b() {
63 reset();
64 {
65 co_await Bug{};
66 assert(ctor_called == 1);
67 assert(dtor_called == 1);
68 assert(alive == 0);
69 }
70 assert(ctor_called == 1);
71 assert(dtor_called == 1);
72 assert(alive == 0);
73
74}
75
76coro2 c() {
77 reset();
78 {
79 auto x = co_yield 42;
80 assert(alive == 1);
81 assert(ctor_called == 1);
82 assert(dtor_called == 0);
83 }
84 assert(alive == 0);
85 assert(ctor_called == 1);
86 assert(dtor_called == 1);
87}
88
89coro2 d() {
90 reset();
91 {
92 co_yield 42;
93 assert(ctor_called == 1);
94 assert(dtor_called == 1);
95 assert(alive == 0);
96 }
97 assert(alive == 0);
98 assert(ctor_called == 1);
99 assert(dtor_called == 1);
100}
101
102int main(int, char**) {
103 a();
104 b();
105 c();
106 d();
107
108 return 0;
109}
110

source code of libcxx/test/std/language.support/support.coroutines/end.to.end/fullexpr-dtor.pass.cpp