1 // { dg-do run } 2 3 // Test co-await in while condition. 4 5 #include "../coro.h" 6 7 // boiler-plate for tests of codegen 8 #include "../coro1-ret-int-yield-int.h" 9 10 /* An awaiter that suspends always and returns an int as the 11 await_resume output. */ 12 13 struct IntAwaiter { 14 int v; IntAwaiterIntAwaiter15 IntAwaiter (int _v) : v(_v) {} await_readyIntAwaiter16 bool await_ready () { return false; } await_suspendIntAwaiter17 void await_suspend (coro::coroutine_handle<>) {} await_resumeIntAwaiter18 int await_resume () { return v; } 19 }; 20 21 /* An awaiter that suspends always and returns a boolean as the 22 await_resume output. The boolean toggles on each call. */ 23 24 struct BoolAwaiter { 25 bool v; BoolAwaiterBoolAwaiter26 BoolAwaiter (bool _v) : v(_v) {} await_readyBoolAwaiter27 bool await_ready () { return false; } await_suspendBoolAwaiter28 void await_suspend (coro::coroutine_handle<>) {} await_resumeBoolAwaiter29 bool await_resume () { v = !v; return v; } 30 }; 31 32 /* We will be able to establish that the second part of the conditional 33 expression is not evaluated (if it was, then we'd need an additional 34 resume to complete the coroutine). */ 35 36 struct coro1 my_coro(int t)37my_coro (int t) 38 { 39 40 bool x = co_await IntAwaiter (t) == 5 || co_await BoolAwaiter (false); 41 42 if (x) 43 co_return 6174; 44 co_return 42; 45 } 46 main()47int main () 48 { 49 PRINT ("main: create coro"); 50 struct coro1 x = my_coro (5); 51 52 if (x.handle.done()) 53 { 54 PRINT ("main: apparently done when we should not be..."); 55 abort (); 56 } 57 58 PRINT ("main: resume initial suspend"); 59 x.handle.resume(); 60 61 PRINT ("main: resume IntAwaiter"); 62 x.handle.resume(); 63 64 // The evaluation of 'co_await IntAwaiter (t) == 5' should be true, thus 65 // the second co_await in the expression will be unexecuted. 66 67 int y = x.handle.promise().get_value(); 68 if ( y != 6174 ) 69 { 70 PRINTF ("main: apparently wrong value : %d\n", y); 71 abort (); 72 } 73 74 if (!x.handle.done()) 75 { 76 PRINT ("main: apparently not done..."); 77 abort (); 78 } 79 PRINT ("main: returning"); 80 return 0; 81 } 82