1 // { dg-do run }
2 
3 // Check that we correctly handle params with non-trivial DTORs and
4 // use the correct copy/move CTORs.
5 
6 #include "../coro.h"
7 #include <vector>
8 
9 // boiler-plate for tests of codegen
10 #include "../coro1-ret-int-yield-int.h"
11 
12 int regular = 0;
13 int copy = 0;
14 int move = 0;
15 
16 /* This is a more sophisticated awaitable... */
17 
18 struct FooAwaitable {
FooAwaitableFooAwaitable19   FooAwaitable(int _v) : value(_v), x(1, _v)
20     {
21       regular++;
22       PRINTF ("FooAwaitable(%d)\n",_v);
23     }
24 
FooAwaitableFooAwaitable25   FooAwaitable(const FooAwaitable& t)
26     {
27       value = t.value;
28       x = t.x;
29       copy++;
30       PRINTF ("FooAwaitable(&), %d\n",value);
31     }
32 
FooAwaitableFooAwaitable33   FooAwaitable(FooAwaitable&& s)
34     {
35       value = s.value;
36       s.value = -1;
37       x = std::move(s.x);
38       s.x = std::vector<int> ();
39       move++;
40       PRINTF ("FooAwaitable(&&), %d\n", value);
41     }
42 
~FooAwaitableFooAwaitable43   ~FooAwaitable() {PRINTF ("~FooAwaitable(), %d\n", value);}
44 
await_readyFooAwaitable45   bool await_ready() { return false; }
await_suspendFooAwaitable46   void await_suspend(coro::coroutine_handle<>) {}
await_resumeFooAwaitable47   int await_resume() { return value + x[0];}
48 
return_valueFooAwaitable49   void return_value(int _v) { value = _v;}
50 
51   int value;
52   std::vector<int> x;
53 };
54 
55 coro1
my_coro(FooAwaitable t_lv,FooAwaitable & t_ref,FooAwaitable && t_rv_ref)56 my_coro (FooAwaitable t_lv, FooAwaitable& t_ref, FooAwaitable&& t_rv_ref)
57 {
58   PRINT ("my_coro");
59   // We are created suspended, so correct operation depends on
60   // the parms being copied.
61   int sum = co_await t_lv;
62   PRINT ("my_coro 1");
63   sum += co_await t_ref;
64   PRINT ("my_coro 2");
65   // This can't work for the rvalue ref, it's always dangling.
66   //sum += co_await t_rv_ref;
67   //PRINT ("my_coro 3");
68   co_return sum;
69 }
70 
main()71 int main ()
72 {
73 
74   PRINT ("main: create coro1");
75   FooAwaitable thing (4);
76   coro1 x = my_coro (FooAwaitable (1), thing, FooAwaitable (2));
77   PRINT ("main: done ramp");
78 
79   if (x.handle.done())
80     abort();
81   x.handle.resume();
82   PRINT ("main: after resume (initial suspend)");
83 
84   // now do the three co_awaits.
85   while(!x.handle.done())
86     x.handle.resume();
87   PRINT ("main: after resuming 2 co_awaits");
88 
89   /* Now we should have the co_returned value.  */
90   int y = x.handle.promise().get_value();
91   if (y != 10)
92     {
93       PRINTF ("main: wrong result (%d).", y);
94       abort ();
95     }
96 
97   if (regular != 3 || copy != 0 || move != 1)
98     {
99       PRINTF ("main: unexpected ctor use (R:%d, C:%d, M:%d)\n",
100 	      regular, copy, move);
101       abort ();
102     }
103 
104   PRINT ("main: returning");
105   return 0;
106 }
107