1 // RUN: %clang_cc1 -verify %s -stdlib=libc++ -std=c++1z -fcoroutines-ts -fsyntax-only
2 
3 namespace std::experimental {
4 template <class Promise = void>
5 struct coroutine_handle;
6 
7 template <>
8 struct coroutine_handle<void> {
9   coroutine_handle() = default;
10   static coroutine_handle from_address(void *) noexcept;
11   void *address() const;
12 };
13 
14 template <class Promise>
15 struct coroutine_handle : public coroutine_handle<> {
16 };
17 
18 template <class... Args>
19 struct void_t_imp {
20   using type = void;
21 };
22 template <class... Args>
23 using void_t = typename void_t_imp<Args...>::type;
24 
25 template <class T, class = void>
26 struct traits_sfinae_base {};
27 
28 template <class T>
29 struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
30   using promise_type = typename T::promise_type;
31 };
32 
33 template <class Ret, class... Args>
34 struct coroutine_traits : public traits_sfinae_base<Ret> {};
35 } // namespace std::experimental
36 
37 struct suspend_never {
38   bool await_ready() noexcept;
39   void await_suspend(std::experimental::coroutine_handle<>) noexcept;
40   void await_resume() noexcept;
41 };
42 
43 struct task {
44   struct promise_type {
initial_suspendtask::promise_type45     auto initial_suspend() { return suspend_never{}; }
final_suspendtask::promise_type46     auto final_suspend() noexcept { return suspend_never{}; }
get_return_objecttask::promise_type47     auto get_return_object() { return task{}; }
unhandled_exceptiontask::promise_type48     static void unhandled_exception() {}
return_voidtask::promise_type49     void return_void() {}
50   };
51 };
52 
53 namespace std::experimental {
54 template <>
55 struct coroutine_handle<task::promise_type> : public coroutine_handle<> {
56   coroutine_handle<task::promise_type> *address() const; // expected-warning {{return type of 'coroutine_handle<>::address should be 'void*'}}
57 };
58 } // namespace std::experimental
59 
60 struct awaitable {
61   bool await_ready();
62 
63   std::experimental::coroutine_handle<task::promise_type>
64   await_suspend(std::experimental::coroutine_handle<> handle);
65   void await_resume();
66 } a;
67 
f()68 task f() {
69   co_await a;
70 }
71 
main()72 int main() {
73   f();
74   return 0;
75 }
76