Mercurial > hg > CbC > CbC_gcc
comparison gcc/testsuite/g++.dg/coroutines/torture/exceptions-test-0.C @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 // { dg-do run } | |
2 | |
3 // Test exceptions. | |
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 coro1 () : handle(0) {} | |
15 coro1 (handle_type _handle) | |
16 : handle(_handle) { | |
17 PRINT("Created coro1 object from handle"); | |
18 } | |
19 coro1 (const coro1 &) = delete; // no copying | |
20 coro1 (coro1 &&s) : handle(s.handle) { | |
21 s.handle = nullptr; | |
22 PRINT("coro1 mv ctor "); | |
23 } | |
24 coro1 &operator = (coro1 &&s) { | |
25 handle = s.handle; | |
26 s.handle = nullptr; | |
27 PRINT("coro1 op= "); | |
28 return *this; | |
29 } | |
30 ~coro1() { | |
31 PRINT("Destroyed coro1"); | |
32 if ( handle ) | |
33 handle.destroy(); | |
34 } | |
35 | |
36 struct suspend_never_prt { | |
37 bool await_ready() const noexcept { return true; } | |
38 void await_suspend(handle_type) const noexcept { PRINT ("susp-never-susp"); } | |
39 void await_resume() const noexcept { PRINT ("susp-never-resume");} | |
40 }; | |
41 | |
42 /* NOTE: this has a DTOR to test that pathway. */ | |
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 struct promise_type { | |
51 int value; | |
52 promise_type() { PRINT ("Created Promise"); } | |
53 ~promise_type() { PRINT ("Destroyed Promise"); } | |
54 | |
55 auto get_return_object () { | |
56 PRINT ("get_return_object: handle from promise"); | |
57 return handle_type::from_promise (*this); | |
58 } | |
59 auto initial_suspend () { | |
60 PRINT ("get initial_suspend (always)"); | |
61 return suspend_always_prt{}; | |
62 } | |
63 auto final_suspend () { | |
64 PRINT ("get final_suspend (always)"); | |
65 return suspend_always_prt{}; | |
66 } | |
67 void return_value (int v) { | |
68 PRINTF ("return_value () %d\n",v); | |
69 value = v; | |
70 } | |
71 auto yield_value (int v) { | |
72 PRINTF ("yield_value () %d and suspend always\n",v); | |
73 value = v; | |
74 return suspend_always_prt{}; | |
75 } | |
76 /* Some non-matching overloads. */ | |
77 auto yield_value (suspend_always_prt s, int x) { | |
78 return s; | |
79 } | |
80 auto yield_value (void) { | |
81 return 42;//suspend_always_prt{}; | |
82 } | |
83 int get_value (void) { return value; } | |
84 | |
85 void unhandled_exception() { | |
86 PRINT ("unhandled_exception: caught one!"); | |
87 gX = -1; | |
88 // returning from here should end up in final_suspend. | |
89 } | |
90 }; | |
91 }; | |
92 | |
93 // So we want to check that the internal behaviour of try/catch is | |
94 // working OK - and that if we have an unhandled exception it is caught | |
95 // by the wrapper that we add to the rewritten func. | |
96 | |
97 struct coro1 throw_and_catch () noexcept | |
98 { | |
99 int caught = 0; | |
100 | |
101 try { | |
102 PRINT ("f: about to yield 42"); | |
103 co_yield 42; | |
104 | |
105 throw (20); | |
106 | |
107 PRINT ("f: about to yield 6174"); | |
108 co_return 6174; | |
109 | |
110 } catch (int x) { | |
111 PRINTF ("f: caught %d\n", x); | |
112 caught = x; | |
113 } | |
114 | |
115 PRINTF ("f: about to yield what we caught %d\n", caught); | |
116 co_yield caught; | |
117 | |
118 throw ("bah"); | |
119 | |
120 PRINT ("f: about to return 22"); | |
121 co_return 22; | |
122 } | |
123 | |
124 int main () | |
125 { | |
126 PRINT ("main: create coro1"); | |
127 struct coro1 x = throw_and_catch (); | |
128 if (x.handle.done()) | |
129 abort(); | |
130 x.handle.resume(); | |
131 PRINT ("main: got coro, resuming.."); | |
132 int y = x.handle.promise().get_value(); | |
133 if ( y != 42 ) | |
134 abort (); | |
135 PRINT ("main: apparently got the expected 42"); | |
136 if (x.handle.done()) | |
137 abort(); | |
138 PRINT ("main: resuming..."); | |
139 x.handle.resume(); | |
140 | |
141 y = x.handle.promise().get_value(); | |
142 if ( y != 20 ) | |
143 abort (); | |
144 PRINT ("main: apparently got 20, which we expected"); | |
145 if (x.handle.done()) | |
146 abort(); | |
147 | |
148 PRINT ("main: resuming..."); | |
149 x.handle.resume(); | |
150 // This should cause the throw of "bah" which is unhandled. | |
151 // We should catch the unhandled exception and then fall through | |
152 // to the final suspend point... thus be "done". | |
153 if (!x.handle.done()) | |
154 { | |
155 PRINT ("main: apparently not done..."); | |
156 abort (); | |
157 } | |
158 // When we caught the unhandled exception we flagged it instead of | |
159 // std::terminate-ing. | |
160 if (gX != -1) | |
161 { | |
162 PRINT ("main: apparently failed to catch"); | |
163 abort (); | |
164 } | |
165 PRINT ("main: returning"); | |
166 return 0; | |
167 } |