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()68task f() { 69 co_await a; 70 } 71 main()72int main() { 73 f(); 74 return 0; 75 } 76