forked from OSchip/llvm-project
107 lines
3.2 KiB
C++
107 lines
3.2 KiB
C++
// This file contains references to sections of the Coroutines TS, which can be
|
|
// found at http://wg21.link/coroutines.
|
|
|
|
// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -Wunused-result
|
|
|
|
namespace std {
|
|
namespace experimental {
|
|
template <class Ret, typename... T>
|
|
struct coroutine_traits { using promise_type = typename Ret::promise_type; };
|
|
// expected-note@-1{{declared here}}
|
|
|
|
template <class Promise = void>
|
|
struct coroutine_handle {
|
|
static coroutine_handle from_address(void *);
|
|
void *address() const noexcept;
|
|
};
|
|
template <>
|
|
struct coroutine_handle<void> {
|
|
template <class PromiseType>
|
|
coroutine_handle(coroutine_handle<PromiseType>);
|
|
void *address() const noexcept;
|
|
};
|
|
|
|
struct suspend_always {
|
|
bool await_ready() { return false; } // expected-note 2 {{must be declared with 'noexcept'}}
|
|
void await_suspend(coroutine_handle<>) {} // expected-note 2 {{must be declared with 'noexcept'}}
|
|
void await_resume() {} // expected-note 2 {{must be declared with 'noexcept'}}
|
|
~suspend_always() noexcept(false); // expected-note 2 {{must be declared with 'noexcept'}}
|
|
};
|
|
} // namespace experimental
|
|
} // namespace std
|
|
|
|
using namespace std::experimental;
|
|
|
|
struct A {
|
|
bool await_ready();
|
|
void await_resume();
|
|
template <typename F>
|
|
void await_suspend(F);
|
|
};
|
|
|
|
struct coro_t {
|
|
struct promise_type {
|
|
coro_t get_return_object();
|
|
suspend_always initial_suspend();
|
|
suspend_always final_suspend(); // expected-note 2 {{must be declared with 'noexcept'}}
|
|
void return_void();
|
|
static void unhandled_exception();
|
|
};
|
|
};
|
|
|
|
coro_t f(int n) { // expected-error {{the expression 'co_await __promise.final_suspend()' is required to be non-throwing}}
|
|
A a{};
|
|
co_await a; // expected-warning {{support for std::experimental::coroutine_traits will be removed}}
|
|
}
|
|
|
|
template <typename T>
|
|
coro_t f_dep(T n) { // expected-error {{the expression 'co_await __promise.final_suspend()' is required to be non-throwing}}
|
|
A a{};
|
|
co_await a;
|
|
}
|
|
|
|
void foo() {
|
|
f_dep<int>(5); // expected-note {{in instantiation of function template specialization 'f_dep<int>' requested here}}
|
|
}
|
|
|
|
struct PositiveFinalSuspend {
|
|
bool await_ready() noexcept;
|
|
coroutine_handle<> await_suspend(coroutine_handle<>) noexcept;
|
|
void await_resume() noexcept;
|
|
};
|
|
|
|
struct correct_coro {
|
|
struct promise_type {
|
|
correct_coro get_return_object();
|
|
suspend_always initial_suspend();
|
|
PositiveFinalSuspend final_suspend() noexcept;
|
|
void return_void();
|
|
static void unhandled_exception();
|
|
};
|
|
};
|
|
|
|
correct_coro f2(int n) {
|
|
co_return;
|
|
}
|
|
|
|
struct NegativeFinalSuspend {
|
|
bool await_ready() noexcept;
|
|
coroutine_handle<> await_suspend(coroutine_handle<>) noexcept;
|
|
void await_resume() noexcept;
|
|
~NegativeFinalSuspend() noexcept(false); // expected-note {{must be declared with 'noexcept'}}
|
|
};
|
|
|
|
struct incorrect_coro {
|
|
struct promise_type {
|
|
incorrect_coro get_return_object();
|
|
suspend_always initial_suspend();
|
|
NegativeFinalSuspend final_suspend() noexcept;
|
|
void return_void();
|
|
static void unhandled_exception();
|
|
};
|
|
};
|
|
|
|
incorrect_coro f3(int n) { // expected-error {{the expression 'co_await __promise.final_suspend()' is required to be non-throwing}}
|
|
co_return;
|
|
}
|