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