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)37 my_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()47 int 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