1 // This file contains references to sections of the Coroutines TS, which can be 2 // found at http://wg21.link/coroutines. 3 4 // RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -Wunused-result 5 6 namespace std { 7 namespace experimental { 8 template <class Ret, typename... T> 9 struct coroutine_traits { using promise_type = typename Ret::promise_type; }; 10 // expected-note@-1{{declared here}} 11 12 template <class Promise = void> 13 struct coroutine_handle { 14 static coroutine_handle from_address(void *); 15 void *address() const noexcept; 16 }; 17 template <> 18 struct coroutine_handle<void> { 19 template <class PromiseType> 20 coroutine_handle(coroutine_handle<PromiseType>); 21 void *address() const noexcept; 22 }; 23 24 struct suspend_always { await_readystd::experimental::suspend_always25 bool await_ready() { return false; } // expected-note 2 {{must be declared with 'noexcept'}} await_suspendstd::experimental::suspend_always26 void await_suspend(coroutine_handle<>) {} // expected-note 2 {{must be declared with 'noexcept'}} await_resumestd::experimental::suspend_always27 void await_resume() {} // expected-note 2 {{must be declared with 'noexcept'}} 28 ~suspend_always() noexcept(false); // expected-note 2 {{must be declared with 'noexcept'}} 29 }; 30 } // namespace experimental 31 } // namespace std 32 33 using namespace std::experimental; 34 35 struct A { 36 bool await_ready(); 37 void await_resume(); 38 template <typename F> 39 void await_suspend(F); 40 }; 41 42 struct coro_t { 43 struct promise_type { 44 coro_t get_return_object(); 45 suspend_always initial_suspend(); 46 suspend_always final_suspend(); // expected-note 2 {{must be declared with 'noexcept'}} 47 void return_void(); 48 static void unhandled_exception(); 49 }; 50 }; 51 f(int n)52coro_t f(int n) { // expected-error {{the expression 'co_await __promise.final_suspend()' is required to be non-throwing}} 53 A a{}; 54 co_await a; // expected-warning {{support for std::experimental::coroutine_traits will be removed}} 55 } 56 57 template <typename T> f_dep(T n)58coro_t f_dep(T n) { // expected-error {{the expression 'co_await __promise.final_suspend()' is required to be non-throwing}} 59 A a{}; 60 co_await a; 61 } 62 foo()63void foo() { 64 f_dep<int>(5); // expected-note {{in instantiation of function template specialization 'f_dep<int>' requested here}} 65 } 66 67 struct PositiveFinalSuspend { 68 bool await_ready() noexcept; 69 coroutine_handle<> await_suspend(coroutine_handle<>) noexcept; 70 void await_resume() noexcept; 71 }; 72 73 struct correct_coro { 74 struct promise_type { 75 correct_coro get_return_object(); 76 suspend_always initial_suspend(); 77 PositiveFinalSuspend final_suspend() noexcept; 78 void return_void(); 79 static void unhandled_exception(); 80 }; 81 }; 82 f2(int n)83correct_coro f2(int n) { 84 co_return; 85 } 86 87 struct NegativeFinalSuspend { 88 bool await_ready() noexcept; 89 coroutine_handle<> await_suspend(coroutine_handle<>) noexcept; 90 void await_resume() noexcept; 91 ~NegativeFinalSuspend() noexcept(false); // expected-note {{must be declared with 'noexcept'}} 92 }; 93 94 struct incorrect_coro { 95 struct promise_type { 96 incorrect_coro get_return_object(); 97 suspend_always initial_suspend(); 98 NegativeFinalSuspend final_suspend() noexcept; 99 void return_void(); 100 static void unhandled_exception(); 101 }; 102 }; 103 f3(int n)104incorrect_coro f3(int n) { // expected-error {{the expression 'co_await __promise.final_suspend()' is required to be non-throwing}} 105 co_return; 106 } 107