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#include <experimental/coroutine>
14#include <cassert>
15
16using namespace std::experimental;
17
18struct coro_t {
19  struct promise_type {
20    coro_t get_return_object() {
21      coroutine_handle<promise_type>{};
22      return {};
23    }
24    suspend_never initial_suspend() { return {}; }
25    suspend_never final_suspend() { return {}; }
26    void return_void() {}
27    static void unhandled_exception() {}
28  };
29};
30
31struct B {
32  ~B() {}
33  bool await_ready() { return true; }
34  B await_resume() { return {}; }
35  template <typename F> void await_suspend(F) {}
36};
37
38
39struct A {
40  ~A() {}
41  bool await_ready() { return true; }
42  int await_resume() { return 42; }
43  template <typename F> void await_suspend(F) {}
44};
45
46int last_value = -1;
47void set_value(int x) {
48  last_value = x;
49}
50
51coro_t f(int n) {
52  if (n == 0) {
53    set_value(0);
54    co_return;
55  }
56  int val = co_await A{};
57  ((void)val);
58  set_value(42);
59}
60
61coro_t g() { B val = co_await B{}; }
62
63int main() {
64  last_value = -1;
65  f(0);
66  assert(last_value == 0);
67  f(1);
68  assert(last_value == 42);
69}
70