• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 // UNSUPPORTED: c++98, c++03, c++11
12 
13 // See https://bugs.llvm.org/show_bug.cgi?id=33271
14 // UNSUPPORTED: ubsan
15 
16 #include <experimental/coroutine>
17 #include <cassert>
18 
19 using namespace std::experimental;
20 
21 struct coro_t {
22   struct promise_type {
get_return_objectcoro_t::promise_type23     coro_t get_return_object() {
24       return coroutine_handle<promise_type>::from_promise(*this);
25     }
initial_suspendcoro_t::promise_type26     suspend_never initial_suspend() { return {}; }
final_suspendcoro_t::promise_type27     suspend_never final_suspend() { return {}; }
return_voidcoro_t::promise_type28     void return_void() {}
unhandled_exceptioncoro_t::promise_type29     void unhandled_exception() {}
30   };
coro_tcoro_t31   coro_t(coroutine_handle<promise_type> hh) : h(hh) {}
32   coroutine_handle<promise_type> h;
33 };
34 
35 struct NoSuspend {
await_readyNoSuspend36   bool await_ready() { return false; }
await_resumeNoSuspend37   void await_resume() {}
await_suspendNoSuspend38   template <typename F> bool await_suspend(F) { return false; }
39 };
40 
41 struct DoSuspend {
await_readyDoSuspend42   bool await_ready() { return false; }
await_resumeDoSuspend43   void await_resume() {}
await_suspendDoSuspend44   template <typename F> bool await_suspend(F) { return true; }
45 };
46 
47 bool f_started, f_resumed = false;
f()48 coro_t f() {
49   f_started = true;
50   co_await DoSuspend{};
51   f_resumed = true;
52 }
53 
54 bool g_started, g_resumed = false;
g()55 coro_t g() {
56   g_started = true;
57   co_await NoSuspend{};
58   g_resumed = true;
59 }
60 
main()61 int main() {
62   assert(!f_started && !f_resumed && !g_started && !g_resumed);
63   auto fret = f();
64   assert(f_started && !f_resumed);
65   fret.h.destroy();
66   assert(f_started && !f_resumed);
67   g();
68   assert(g_started && g_resumed);
69 }
70