1 // Test handling of the case where we have a void g-r-o and a non-void
2 // and non-class-type ramp return.
3 
4 #include "coro.h"
5 
6 int g_promise = -1;
7 
8 template<typename R, typename HandleRef, typename ...T>
9 struct std::coroutine_traits<R, HandleRef, T...> {
10     struct promise_type {
11         promise_type (HandleRef h, T ...args)
12         { h = std::coroutine_handle<promise_type>::from_promise (*this);
13           PRINT ("Created Promise");
14           g_promise = 1;
15         }
16 	~promise_type () { PRINT ("Destroyed Promise"); g_promise = 0;}
17         void get_return_object() {}
18 
19         auto initial_suspend() {
20           return std::suspend_always{};
21          }
22         auto final_suspend() { return std::suspend_never{}; }
23 
24         void return_void() {}
25         void unhandled_exception() {}
26     };
27 };
28 
29 int
30 my_coro (std::coroutine_handle<>& h)
31 {
32   PRINT ("coro1: about to return");
33   co_return;
34 } // { dg-error {cannot initialize a return object of type 'int' with an rvalue of type 'void'} }
35 
36 int main ()
37 {
38   std::coroutine_handle<> h;
39   int t = my_coro (h);
40 
41   if (h.done())
42     {
43       PRINT ("main: apparently was already done...");
44       abort ();
45     }
46 
47   // initial suspend.
48   h.resume ();
49 
50   // The coro should have self-destructed.
51   if (g_promise)
52     {
53       PRINT ("main: apparently we did not complete...");
54       abort ();
55     }
56 
57   PRINT ("main: returning");
58   return t;
59 }
60