source: doc/working/exception/impl/test-main.c@ 578e6037

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 578e6037 was e1055441, checked in by Andrew Beach <ajbeach@…>, 8 years ago

Now tests finally during unwind.

  • Property mode set to 100644
File size: 9.3 KB
Line 
1#include "exception.h"
2
3// Use: gcc -fexceptions -Wall -Werror -g exception.c test-main.c
4
5#include <stdio.h>
6#include <stdbool.h>
7
8// Helps with manual translation. It may or may not get folded into the
9// header, that depends on how it interacts with concurancy.
10void __try_resume_node_new(struct __try_resume_node * node,
11 _Bool (*handler)(exception except)) {
12 node->next = shared_stack.top_resume;
13 shared_stack.top_resume = node;
14 node->try_to_handle = handler;
15}
16
17// Local Print On Exit:
18struct raii_base_type {
19 const char * area;
20};
21
22void raii_dtor(struct raii_base_type * this) {
23 printf("Exiting: %s\n", this->area);
24}
25
26#define raii_t __attribute__((cleanup(raii_dtor))) struct raii_base_type
27
28// ===========================================================================
29// Runtime code (post-translation).
30void terminate(int except_value) {
31 raii_t a = {"terminate function"};
32 __throw_terminate(except_value);
33 printf("terminate returned\n");
34}
35
36void resume(int except_value) {
37 raii_t a = {"resume function"};
38 __throw_resume(except_value);
39 printf("resume returned\n");
40}
41
42// Termination Test: Two handlers: no catch, catch
43void bar() {
44 raii_t a = {"bar function"};
45 {
46 void bar_try1() {
47 terminate(4);
48 }
49 void bar_catch1(int index, exception except) {
50 switch(except) {
51 case 1:
52 printf("bar caught exception 3.\n");
53 break;
54 default:
55 printf("INVALID INDEX in bar: %d (%d)\n", index, except);
56 }
57 }
58 int bar_match1(exception except) {
59 if (3 == except) {
60 return 1;
61 } else {
62 return 0;
63 }
64 }
65 __try_terminate(bar_try1, bar_catch1, bar_match1);
66 }
67}
68
69void foo() {
70 raii_t a = {"foo function"};
71 {
72 void foo_try1() {
73 bar();
74 }
75 void foo_catch1(int index, exception except) {
76 switch(index) {
77 case 1:
78 printf("foo caught exception 4.\n");
79 break;
80 case 2:
81 printf("foo caught exception 2.\n");
82 break;
83 default:
84 printf("INVALID INDEX in foo: %d (%d)\n", index, except);
85 }
86 }
87 int foo_match1(exception except) {
88 if (4 == except) {
89 return 1;
90 } else if (2 == except) {
91 return 2;
92 } else {
93 return 0;
94 }
95 }
96 __try_terminate(foo_try1, foo_catch1, foo_match1);
97 }
98}
99
100// Resumption Two Handler Test: no catch, catch.
101void beta() {
102 raii_t a = {"beta function"};
103 {
104 bool beta_handle1(exception except) {
105 if (3 == except) {
106 printf("beta caught exception 3\n");
107 return true;
108 } else {
109 return false;
110 }
111 }
112 struct __try_resume_node node
113 __attribute__((cleanup(__try_resume_cleanup)));
114 __try_resume_node_new(&node, beta_handle1);
115 {
116 resume(4);
117 }
118 }
119}
120void alpha() {
121 raii_t a = {"alpha function"};
122 {
123 bool alpha_handle1(exception except) {
124 if (2 == except) {
125 printf("alpha caught exception 2\n");
126 return true;
127 } else if (4 == except) {
128 printf("alpha caught exception 4\n");
129 return true;
130 } else {
131 return false;
132 }
133 }
134 struct __try_resume_node node
135 __attribute__((cleanup(__try_resume_cleanup)));
136 __try_resume_node_new(&node, alpha_handle1);
137 {
138 beta();
139 }
140 }
141}
142
143// Finally Test:
144void farewell(bool jump) {
145 {
146 void farewell_finally1() {
147 printf("See you next time\n");
148 }
149 struct __cleanup_hook __hidden_hook
150 __attribute__((cleanup(farewell_finally1)));
151 {
152 if (jump) {
153 printf("jump out of farewell\n");
154 goto endoffunction;
155 } else {
156 printf("walk out of farewell\n");
157 }
158 }
159 }
160 endoffunction:
161 printf("leaving farewell\n");
162}
163
164// Resume-to-Terminate Test:
165void fallback() {
166 {
167 void fallback_try1() {
168 resume(1);
169 }
170 void fallback_catch1(int index, exception except) {
171 switch (index) {
172 case 1:
173 printf("fallback caught termination 1\n");
174 break;
175 default:
176 printf("INVALID INDEX in fallback: %d (%d)\n", index, except);
177 }
178 }
179 int fallback_match1(exception except) {
180 if (1 == except) {
181 return 1;
182 } else {
183 return 0;
184 }
185 }
186 __try_terminate(fallback_try1, fallback_catch1, fallback_match1);
187 }
188}
189
190// Terminate Throw New Exception:
191void terminate_swap() {
192 raii_t a = {"terminate_swap"};
193 {
194 void fn_try1() {
195 terminate(2);
196 }
197 void fn_catch1(int index, exception except) {
198 switch (index) {
199 case 1:
200 terminate(1);
201 break;
202 default:
203 printf("INVALID INDEX in terminate_swap: %d (%d)\n",
204 index, except);
205 }
206 }
207 int fn_match1(exception except) {
208 if (2 == except) {
209 return 1;
210 } else {
211 return 0;
212 }
213 }
214 __try_terminate(fn_try1, fn_catch1, fn_match1);
215 }
216}
217
218void terminate_swapped() {
219 raii_t a = {"terminate_swapped"};
220 {
221 void fn_try1() {
222 terminate_swap();
223 }
224 void fn_catch1(int index, exception except) {
225 switch (index) {
226 case 1:
227 printf("terminate_swapped caught exception 1\n");
228 break;
229 default:
230 printf("INVALID INDEX in terminate_swapped: %d (%d)\n",
231 index, except);
232 }
233 }
234 int fn_match1(exception except) {
235 if (1 == except) {
236 return 1;
237 } else {
238 return 0;
239 }
240 }
241 __try_terminate(fn_try1, fn_catch1, fn_match1);
242 }
243}
244
245// Resume Throw New Exception:
246void resume_swap() {
247 raii_t a = {"terminate_swap"};
248 {
249 bool fn_handle1(exception except) {
250 if (2 == except) {
251 resume(1);
252 return true;
253 } else {
254 return false;
255 }
256 }
257 struct __try_resume_node node
258 __attribute__((cleanup(__try_resume_cleanup)));
259 __try_resume_node_new(&node, fn_handle1);
260 {
261 resume(2);
262 }
263 }
264}
265
266void resume_swapped() {
267 {
268 bool fn_handle1(exception except) {
269 if (1 == except) {
270 printf("resume_swapped caught exception 1\n");
271 return true;
272 } else {
273 return false;
274 }
275 }
276 struct __try_resume_node node
277 __attribute__((cleanup(__try_resume_cleanup)));
278 __try_resume_node_new(&node, fn_handle1);
279 {
280 resume_swap();
281 }
282 }
283}
284
285// Terminate Rethrow:
286// I don't have an implementation for this.
287void reterminate() {
288 {
289 void fn_try1() {
290 void fn_try2() {
291 terminate(1);
292 }
293 void fn_catch2(int index, exception except) {
294 switch (index) {
295 case 1:
296 printf("reterminate 2 caught and "
297 "will rethrow exception 1\n");
298 __rethrow_terminate();
299 break;
300 default:
301 printf("INVALID INDEX in reterminate 2: %d (%d)\n",
302 index, except);
303 }
304 }
305 int fn_match2(exception except) {
306 if (1 == except) {
307 return 1;
308 } else {
309 return 0;
310 }
311 }
312 __try_terminate(fn_try2, fn_catch2, fn_match2);
313 }
314 void fn_catch1(int index, exception except) {
315 switch (index) {
316 case 1:
317 printf("reterminate 1 caught exception 1\n");
318 break;
319 default:
320 printf("INVALID INDEX in reterminate 1: %d (%d)\n",
321 index, except);
322 }
323 }
324 int fn_match1(exception except) {
325 if (1 == except) {
326 return 1;
327 } else {
328 return 0;
329 }
330 }
331 __try_terminate(fn_try1, fn_catch1, fn_match1);
332 }
333}
334
335// Resume Rethrow:
336void reresume() {
337 {
338 bool reresume_handle1(exception except) {
339 if (1 == except) {
340 printf("reresume 1 caught exception 1\n");
341 return true;
342 } else {
343 return false;
344 }
345 }
346 struct __try_resume_node node
347 __attribute__((cleanup(__try_resume_cleanup)));
348 __try_resume_node_new(&node, reresume_handle1);
349 {
350 bool reresume_handle2(exception except) {
351 if (1 == except) {
352 printf("reresume 2 caught and rethrows exception 1\n");
353 return false;
354 } else {
355 return false;
356 }
357 }
358 struct __try_resume_node node
359 __attribute__((cleanup(__try_resume_cleanup)));
360 __try_resume_node_new(&node, reresume_handle2);
361 {
362 resume(1);
363 }
364 }
365 }
366}
367
368// Terminate-Resume interaction:
369void fum() {
370 // terminate block, call resume
371 {
372 void fum_try1() {
373 resume(3);
374 }
375 void fum_catch1(int index, exception except) {
376 switch (index) {
377 case 1:
378 printf("fum caught exception 3\n");
379 break;
380 default:
381 printf("INVALID INDEX in fum: %d (%d)\n", index, except);
382 }
383 }
384 int fum_match1(exception except) {
385 if (3 == except) {
386 return 1;
387 } else {
388 return 0;
389 }
390 }
391 __try_terminate(fum_try1, fum_catch1, fum_match1);
392 }
393}
394
395void foe() {
396 // resume block, call terminate
397 {
398 bool foe_handle1(exception except) {
399 if (3 == except) {
400 printf("foe caught exception 3\n");
401 return true;
402 } else {
403 return false;
404 }
405 }
406 struct __try_resume_node node
407 __attribute__((cleanup(__try_resume_cleanup)));
408 __try_resume_node_new(&node, foe_handle1);
409 {
410 terminate(3);
411 }
412 }
413}
414
415void fy() {
416 // terminate block calls fum, call foe
417 {
418 void fy_try1() {
419 foe();
420 }
421 void fy_catch1(int index, exception except) {
422 switch (index) {
423 case 1:
424 printf("fy caught exception 3\n");
425 fum();
426 break;
427 default:
428 printf("INVALID INDEX in fy: %d (%d)\n", index, except);
429 }
430 }
431 int fy_match1(exception except) {
432 if (3 == except) {
433 return 1;
434 } else {
435 return 0;
436 }
437 }
438 __try_terminate(fy_try1, fy_catch1, fy_match1);
439 }
440}
441
442void fee() {
443 // resume block, call fy
444 {
445 bool fee_handle1(exception except) {
446 if (3 == except) {
447 printf("fee caught exception 3\n");
448 return true;
449 } else {
450 return false;
451 }
452 }
453 struct __try_resume_node node
454 __attribute__((cleanup(__try_resume_cleanup)));
455 __try_resume_node_new(&node, fee_handle1);
456 {
457 fy();
458 }
459 }
460}
461
462
463// main: choose which tests to run
464int main(int argc, char * argv[]) {
465 raii_t a = {"main function"};
466
467 foo(); printf("\n");
468 alpha(); printf("\n");
469 farewell(false); printf("\n");
470 farewell(true); printf("\n");
471 fallback(); printf("\n");
472 terminate_swapped(); printf("\n");
473 resume_swapped(); printf("\n");
474 reterminate(); printf("\n");
475 reresume(); printf("\n");
476 fee(); printf("\n");
477 // Uncaught termination test.
478 terminate(7);
479}
Note: See TracBrowser for help on using the repository browser.