1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++03, c++11 11 12 #include <experimental/coroutine> 13 #include <cassert> 14 15 #include "test_macros.h" 16 17 using namespace std::experimental; 18 19 int alive = 0; 20 int ctor_called = 0; 21 int dtor_called = 0; reset()22void reset() { 23 assert(alive == 0); 24 alive = 0; 25 ctor_called = 0; 26 dtor_called = 0; 27 } 28 struct Noisy { NoisyNoisy29 Noisy() { ++alive; ++ctor_called; } ~NoisyNoisy30 ~Noisy() { --alive; ++dtor_called; } 31 #if TEST_STD_VER > 14 32 Noisy(Noisy const&) = delete; 33 #else 34 // FIXME: This test depends on copy elision taking place in C++14 35 // (pre-C++17 guaranteed copy elision) 36 Noisy(Noisy const&); 37 #endif 38 }; 39 40 struct Bug { await_readyBug41 bool await_ready() { return true; } await_suspendBug42 void await_suspend(std::experimental::coroutine_handle<>) {} await_resumeBug43 Noisy await_resume() { return {}; } 44 }; 45 struct coro2 { 46 struct promise_type { initial_suspendcoro2::promise_type47 suspend_never initial_suspend() { return{}; } final_suspendcoro2::promise_type48 suspend_never final_suspend() noexcept { return {}; } get_return_objectcoro2::promise_type49 coro2 get_return_object() { return{}; } return_voidcoro2::promise_type50 void return_void() {} yield_valuecoro2::promise_type51 Bug yield_value(int) { return {}; } unhandled_exceptioncoro2::promise_type52 void unhandled_exception() {} 53 }; 54 }; 55 56 // Checks that destructors are correctly invoked for the object returned by 57 // coawait. a()58coro2 a() { 59 reset(); 60 { 61 auto x = co_await Bug{}; 62 assert(alive == 1); 63 assert(ctor_called == 1); 64 assert(dtor_called == 0); 65 ((void)x); 66 } 67 assert(alive == 0); 68 assert(dtor_called == 1); 69 } 70 b()71coro2 b() { 72 reset(); 73 { 74 (void)(co_await Bug{}); 75 assert(ctor_called == 1); 76 assert(dtor_called == 1); 77 assert(alive == 0); 78 } 79 assert(ctor_called == 1); 80 assert(dtor_called == 1); 81 assert(alive == 0); 82 83 } 84 c()85coro2 c() { 86 reset(); 87 { 88 auto x = co_yield 42; 89 assert(alive == 1); 90 assert(ctor_called == 1); 91 assert(dtor_called == 0); 92 } 93 assert(alive == 0); 94 assert(ctor_called == 1); 95 assert(dtor_called == 1); 96 } 97 d()98coro2 d() { 99 reset(); 100 { 101 (void)(co_yield 42); 102 assert(ctor_called == 1); 103 assert(dtor_called == 1); 104 assert(alive == 0); 105 } 106 assert(alive == 0); 107 assert(ctor_called == 1); 108 assert(dtor_called == 1); 109 } 110 main(int,char **)111int main(int, char**) { 112 a(); 113 b(); 114 c(); 115 d(); 116 117 return 0; 118 } 119