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