Mercurial > hg > CbC > CbC_gcc
comparison gcc/testsuite/g++.dg/coroutines/torture/exceptions-test-01-n4849-a.C @ 152:2b5abeee2509
update gcc11
author | anatofuz |
---|---|
date | Mon, 25 May 2020 07:50:57 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
145:1830386684a0 | 152:2b5abeee2509 |
---|---|
1 // { dg-do run } | |
2 | |
3 // Test exceptions in the initial await expression, per n4849. | |
4 | |
5 #include "../coro.h" | |
6 #include <exception> | |
7 | |
8 int gX = 0; | |
9 | |
10 struct coro1 { | |
11 struct promise_type; | |
12 using handle_type = coro::coroutine_handle<coro1::promise_type>; | |
13 handle_type handle; | |
14 | |
15 coro1 () : handle(0) {} | |
16 coro1 (handle_type _handle) | |
17 : handle(_handle) { | |
18 PRINT("Created coro1 object from handle"); | |
19 } | |
20 coro1 (const coro1 &) = delete; // no copying | |
21 coro1 (coro1 &&s) : handle(s.handle) { | |
22 s.handle = nullptr; | |
23 PRINT("coro1 mv ctor "); | |
24 } | |
25 coro1 &operator = (coro1 &&s) { | |
26 handle = s.handle; | |
27 s.handle = nullptr; | |
28 PRINT("coro1 op= "); | |
29 return *this; | |
30 } | |
31 ~coro1() { | |
32 PRINT("Destroyed coro1"); | |
33 if ( handle ) | |
34 handle.destroy(); | |
35 } | |
36 | |
37 struct suspend_never_prt { | |
38 bool await_ready() const noexcept { return true; } | |
39 void await_suspend(handle_type) const noexcept { PRINT ("susp-never-susp"); } | |
40 void await_resume() const noexcept { PRINT ("susp-never-resume");} | |
41 }; | |
42 | |
43 struct suspend_always_prt { | |
44 bool await_ready() const noexcept { return false; } | |
45 void await_suspend(handle_type) const noexcept { PRINT ("susp-always-susp"); } | |
46 void await_resume() const noexcept { PRINT ("susp-always-resume"); } | |
47 ~suspend_always_prt() { PRINT ("susp-always-DTOR"); } | |
48 }; | |
49 | |
50 /* Constructing this with: | |
51 * a value of '1' will cause the initial suspend await_suspend() | |
52 call to throw. | |
53 * a value of '2' will cause the await resume to throw. */ | |
54 struct suspend_always_susp_throws_prt { | |
55 int thrower; | |
56 suspend_always_susp_throws_prt (int _t) : thrower(_t) {} | |
57 bool await_ready() const noexcept { return false; } | |
58 | |
59 void await_suspend(handle_type) const | |
60 { PRINT ("suspend_always_susp_throws_prt:await_suspend"); | |
61 if (thrower == 1) | |
62 throw (42); | |
63 } | |
64 void await_resume() const | |
65 { PRINT ("suspend_always_susp_throws_prt:await_resume"); | |
66 if (thrower == 2) | |
67 throw (6174); | |
68 } | |
69 ~suspend_always_susp_throws_prt() { PRINT ("suspend_always_susp_throws_prt-DTOR"); } | |
70 }; | |
71 | |
72 struct promise_type { | |
73 int throw_control = 0; | |
74 int value; | |
75 promise_type(int k) : throw_control(k), value(-373) | |
76 { PRINTF ("Created Promise with %d\n", k);} | |
77 | |
78 ~promise_type() { PRINT ("Destroyed Promise"); } | |
79 | |
80 auto get_return_object () { | |
81 PRINT ("get_return_object: handle from promise"); | |
82 return handle_type::from_promise (*this); | |
83 } | |
84 // This provides the tests for what catches exceptions thrown at | |
85 // different points in the initial await expression. | |
86 auto initial_suspend () { | |
87 PRINT ("get initial_suspend (always)"); | |
88 return suspend_always_susp_throws_prt(throw_control); | |
89 } | |
90 auto final_suspend () { | |
91 PRINT ("get final_suspend (always)"); | |
92 return suspend_always_prt{}; | |
93 } | |
94 void return_value (int v) { | |
95 PRINTF ("return_value () %d\n",v); | |
96 value = v; | |
97 } | |
98 auto yield_value (int v) { | |
99 PRINTF ("yield_value () %d and suspend always\n",v); | |
100 value = v; | |
101 return suspend_always_prt{}; | |
102 } | |
103 int get_value (void) { return value; } | |
104 | |
105 void unhandled_exception() { | |
106 PRINT ("unhandled_exception: caught one!"); | |
107 gX = -11; | |
108 // returning from here should end up in final_suspend. | |
109 } | |
110 }; | |
111 }; | |
112 | |
113 // This doesn't have to do much - we only need to exercise the initial | |
114 // await expression. | |
115 | |
116 struct coro1 | |
117 n4849_ia_thrower (int k) | |
118 { | |
119 int caught = 0; | |
120 PRINT ("f: about to return 22"); | |
121 co_return 22; | |
122 } | |
123 | |
124 int main () | |
125 { | |
126 { | |
127 /* Case 0 - nothing should throw. */ | |
128 struct coro1 x0; | |
129 try { | |
130 x0 = n4849_ia_thrower (0); | |
131 } catch (...) { | |
132 PRINT ("main: case 0 ctor threw?"); | |
133 abort (); | |
134 } | |
135 /* Resume the initial suspend expression. */ | |
136 PRINT ("main: got coro, resuming.."); | |
137 x0.handle.resume(); | |
138 int y = x0.handle.promise().get_value(); | |
139 if ( y != 22 ) | |
140 { | |
141 PRINT ("main: case 0 got the wrong answer."); | |
142 abort (); | |
143 } | |
144 if (!x0.handle.done()) | |
145 { | |
146 PRINT ("main: case 0 not done."); | |
147 abort (); | |
148 } | |
149 if (gX != 0) | |
150 { | |
151 PRINT ("main: case 0 body threw?"); | |
152 abort (); | |
153 } | |
154 } | |
155 | |
156 { | |
157 /* Case 1 - initial suspend should throw and thus be caught by the | |
158 ramp's caller. */ | |
159 struct coro1 x1; | |
160 try { | |
161 x1 = n4849_ia_thrower (1); | |
162 } catch (int message) { | |
163 PRINTF ("main: caught an int %d\n", message); | |
164 if (message != 42) | |
165 { | |
166 PRINT ("main: unexpected value?"); | |
167 abort (); | |
168 } | |
169 } catch (...) { | |
170 PRINT ("main: case 1 ctor threw something else?"); | |
171 abort (); | |
172 } | |
173 if (gX != 0) | |
174 { | |
175 PRINT ("main: case 0 body threw (how?)"); | |
176 abort (); | |
177 } | |
178 } | |
179 | |
180 { | |
181 /* Case 2 - the await_resume from the initial await expression throws | |
182 this should be caught by the regular function body wrapper. */ | |
183 struct coro1 x2; | |
184 try { | |
185 x2 = n4849_ia_thrower (2); | |
186 } catch (...) { | |
187 PRINT ("main: case 2 ctor threw?"); | |
188 abort (); | |
189 } | |
190 // We now resume - and expect the await_resume to throw which should | |
191 // be caught by unhandled_exception(). | |
192 PRINT ("main: got coro, resuming.."); | |
193 x2.handle.resume(); | |
194 int y = x2.handle.promise().get_value(); | |
195 if ( y != -373 ) | |
196 { | |
197 PRINT ("main: case 2 got the wrong answer."); | |
198 abort (); | |
199 } | |
200 if (!x2.handle.done()) | |
201 { | |
202 PRINT ("main: case 2 not done."); | |
203 abort (); | |
204 } | |
205 if (gX != -11) | |
206 { | |
207 PRINT ("main: n4849_is_thrower await_resume exception not caught"); | |
208 abort (); | |
209 } | |
210 } | |
211 PRINT ("main: returning"); | |
212 return 0; | |
213 } |