// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11 #include #include #include "test_macros.h" using namespace std::experimental; int alive = 0; int ctor_called = 0; int dtor_called = 0; void reset() { assert(alive == 0); alive = 0; ctor_called = 0; dtor_called = 0; } struct Noisy { Noisy() { ++alive; ++ctor_called; } ~Noisy() { --alive; ++dtor_called; } #if TEST_STD_VER > 14 Noisy(Noisy const&) = delete; #else // FIXME: This test depends on copy elision taking place in C++14 // (pre-C++17 guaranteed copy elision) Noisy(Noisy const&); #endif }; struct Bug { bool await_ready() { return true; } void await_suspend(std::experimental::coroutine_handle<>) {} Noisy await_resume() { return {}; } }; struct coro2 { struct promise_type { suspend_never initial_suspend() { return{}; } suspend_never final_suspend() noexcept { return {}; } coro2 get_return_object() { return{}; } void return_void() {} Bug yield_value(int) { return {}; } void unhandled_exception() {} }; }; // Checks that destructors are correctly invoked for the object returned by // coawait. coro2 a() { reset(); { auto x = co_await Bug{}; assert(alive == 1); assert(ctor_called == 1); assert(dtor_called == 0); ((void)x); } assert(alive == 0); assert(dtor_called == 1); } coro2 b() { reset(); { (void)(co_await Bug{}); assert(ctor_called == 1); assert(dtor_called == 1); assert(alive == 0); } assert(ctor_called == 1); assert(dtor_called == 1); assert(alive == 0); } coro2 c() { reset(); { auto x = co_yield 42; assert(alive == 1); assert(ctor_called == 1); assert(dtor_called == 0); } assert(alive == 0); assert(ctor_called == 1); assert(dtor_called == 1); } coro2 d() { reset(); { (void)(co_yield 42); assert(ctor_called == 1); assert(dtor_called == 1); assert(alive == 0); } assert(alive == 0); assert(ctor_called == 1); assert(dtor_called == 1); } int main(int, char**) { a(); b(); c(); d(); return 0; }