1 //  { dg-additional-options "-fsyntax-only" }
2 
3 #if __has_include(<coroutine>)
4 #include <coroutine>
5 #else
6 #include <experimental/coroutine>
7 namespace std {
8   using namespace std::experimental;
9 }
10 #endif
11 
12 class promise;
13 
14 struct finalSuspendAwaiter {
15   int x;
finalSuspendAwaiterfinalSuspendAwaiter16   finalSuspendAwaiter () : x(0) { }
finalSuspendAwaiterfinalSuspendAwaiter17   finalSuspendAwaiter (int _x) : x(_x) { }
noexceptfinalSuspendAwaiter18   ~finalSuspendAwaiter() noexcept(false) { }
await_readyfinalSuspendAwaiter19   bool await_ready() const noexcept(true) { return false; }
await_suspendfinalSuspendAwaiter20   void await_suspend(std::coroutine_handle<>) const noexcept(false) { }
21   // { dg-error {the expression 'finalSuspendAwaiter::await_suspend' is required to be non-throwing} "" { target *-*-* } .-1 }
await_resumefinalSuspendAwaiter22   int await_resume() const noexcept(false) { return x; }
23 };
24 
25 struct finalSuspendObj {
26   int x;
finalSuspendObjfinalSuspendObj27   finalSuspendObj () : x(0) { }
finalSuspendObjfinalSuspendObj28   finalSuspendObj (int _x) : x(_x) { }
noexceptfinalSuspendObj29   ~finalSuspendObj () noexcept(true) {}
30 
co_awaitfinalSuspendObj31   finalSuspendAwaiter operator co_await() const & noexcept(true) {
32     return {x};
33   }
34 };
35 
36 struct task {
37   struct promise_type {
get_return_objecttask::promise_type38   task get_return_object() noexcept { return {}; }
initial_suspendtask::promise_type39   std::suspend_never initial_suspend() noexcept { return {}; }
40 
final_suspendtask::promise_type41   finalSuspendObj final_suspend() noexcept { return {3}; }
42 
return_voidtask::promise_type43   void return_void() noexcept {}
unhandled_exceptiontask::promise_type44   void unhandled_exception() noexcept {}
45   };
46 };
47 
48 // This should be ill-formed since final_suspend() is potentially throwing.
f()49 task f() {
50   co_return;
51 }
52