]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/testsuite/gdc.test/runnable/eh.d
Add D front-end, libphobos library, and D2 testsuite.
[thirdparty/gcc.git] / gcc / testsuite / gdc.test / runnable / eh.d
1 // PERMUTE_ARGS: -O -fPIC
2
3 extern(C) int printf(const char*, ...);
4
5 /****************************************************/
6
7 class Abc : Exception
8 {
9 this()
10 {
11 super("");
12 }
13 int i;
14 }
15
16 int y;
17
18 alias int boo;
19
20 void foo(int x)
21 {
22 y = cast(boo)1;
23 L6:
24 try
25 {
26 printf("try 1\n");
27 y += 4;
28 if (y == 5)
29 goto L6;
30 y += 3;
31 }
32 finally
33 {
34 y += 5;
35 printf("finally 1\n");
36 }
37 try
38 {
39 printf("try 2\n");
40 y = 1;
41 if (y == 4)
42 goto L6;
43 y++;
44 }
45 catch (Abc c)
46 {
47 printf("catch 2\n");
48 y = 2 + c.i;
49 }
50 y++;
51 printf("done\n");
52 }
53
54 /****************************************************/
55
56
57 class IntException : Exception
58 {
59 this(int i)
60 {
61 m_i = i;
62 super("");
63 }
64
65 int getValue()
66 {
67 return m_i;
68 }
69
70 int m_i;
71 }
72
73
74 void test2()
75 {
76 int cIterations = 10;
77
78 int i;
79 long total_x = 0;
80 long total_nox = 0;
81
82 for(int WARMUPS = 2; WARMUPS-- > 0; )
83 {
84 for(total_x = 0, i = 0; i < cIterations; ++i)
85 {
86 total_nox += fn2_nox();
87 }
88 printf("foo\n");
89
90 for(total_nox = 0, i = 0; i < cIterations; ++i)
91 {
92 printf("i = %d\n", i);
93 try
94 {
95 int z = 1;
96
97 throw new IntException(z);
98 }
99 catch(IntException x)
100 {
101 printf("catch, i = %d\n", i);
102 total_x += x.getValue();
103 }
104 }
105 }
106
107 printf("iterations %d totals: %ld, %ld\n", cIterations, total_x, total_nox);
108 }
109
110 int fn2_nox()
111 {
112 return 47;
113 }
114
115
116 /****************************************************/
117
118 void test3()
119 {
120 static int x;
121 try
122 {
123 }
124 finally
125 {
126 printf("a\n");
127 assert(x == 0);
128 x++;
129 }
130 printf("--\n");
131 assert(x == 1);
132 try
133 {
134 printf("tb\n");
135 assert(x == 1);
136 }
137 finally
138 {
139 printf("b\n");
140 assert(x == 1);
141 x++;
142 }
143 assert(x == 2);
144 }
145
146 /****************************************************/
147
148 class Tester
149 {
150 this(void delegate() dg_) { dg = dg_; }
151 void delegate() dg;
152 void stuff() { dg(); }
153 }
154
155 void test4()
156 {
157 printf("Starting test\n");
158
159 int a = 0;
160 int b = 0;
161 int c = 0;
162 int d = 0;
163
164 try
165 {
166 a++;
167 throw new Exception("test1");
168 a++;
169 }
170 catch(Exception e)
171 {
172 auto es = e.toString();
173 printf("%.*s\n", es.length, es.ptr);
174 b++;
175 }
176 finally
177 {
178 c++;
179 }
180
181 printf("initial test.\n");
182
183 assert(a == 1);
184 assert(b == 1);
185 assert(c == 1);
186
187 printf("pass\n");
188
189 Tester t = new Tester(
190 delegate void()
191 {
192 try
193 {
194 a++;
195 throw new Exception("test2");
196 a++;
197 }
198 catch(Exception e)
199 {
200 b++;
201 throw e;
202 b++;
203 }
204 });
205
206 try
207 {
208 c++;
209 t.stuff();
210 c++;
211 }
212 catch(Exception e)
213 {
214 d++;
215 string es = e.toString;
216 printf("%.*s\n", es.length, es.ptr);
217 }
218
219 assert(a == 2);
220 assert(b == 2);
221 assert(c == 2);
222 assert(d == 1);
223
224
225 int q0 = 0;
226 int q1 = 0;
227 int q2 = 0;
228 int q3 = 0;
229
230 Tester t2 = new Tester(
231 delegate void()
232 {
233 try
234 {
235 q0++;
236 throw new Exception("test3");
237 q0++;
238 }
239 catch(Exception e)
240 {
241 printf("Never called.\n");
242 q1++;
243 throw e;
244 q1++;
245 }
246 });
247
248 try
249 {
250 q2++;
251 t2.stuff();
252 q2++;
253 }
254 catch(Exception e)
255 {
256 q3++;
257 string es = e.toString;
258 printf("%.*s\n", es.length, es.ptr);
259 }
260
261 assert(q0 == 1);
262 assert(q1 == 1);
263 assert(q2 == 1);
264 assert(q3 == 1);
265
266 printf("Passed!\n");
267 }
268
269 /****************************************************/
270
271 void test5()
272 {
273 char[] result;
274 int i = 3;
275 while(i--)
276 {
277 try
278 {
279 printf("i: %d\n", i);
280 result ~= 't';
281 if (i == 1)
282 continue;
283 }
284 finally
285 {
286 printf("finally\n");
287 result ~= cast(char)('a' + i);
288 }
289 }
290 printf("--- %.*s", result.length, result.ptr);
291 if (result != "tctbta")
292 assert(0);
293 }
294
295 /****************************************************/
296
297 void test6()
298 {
299 char[] result;
300
301 while (true)
302 {
303 try
304 {
305 printf("one\n");
306 result ~= 'a';
307 break;
308 }
309 finally
310 {
311 printf("two\n");
312 result ~= 'b';
313 }
314 }
315 printf("three\n");
316 result ~= 'c';
317 if (result != "abc")
318 assert(0);
319 }
320
321 /****************************************************/
322
323 string a7;
324
325 void doScan(int i)
326 {
327 a7 ~= "a";
328 try
329 {
330 try
331 {
332 a7 ~= "b";
333 return;
334 }
335 finally
336 {
337 a7 ~= "c";
338 }
339 }
340 finally
341 {
342 a7 ~= "d";
343 }
344 }
345
346 void test7()
347 {
348 doScan(0);
349 assert(a7 == "abcd");
350 }
351
352
353 /****************************************************
354 * Exception chaining tests. See also test4.d
355 ****************************************************/
356 int result1513;
357
358 void bug1513a()
359 {
360 throw new Exception("d");
361 }
362
363 void bug1513b()
364 {
365 try
366 {
367 try
368 {
369 bug1513a();
370 }
371 finally
372 {
373 result1513 |=4;
374 throw new Exception("f");
375 }
376 }
377 catch(Exception e)
378 {
379 assert(e.msg == "d");
380 assert(e.next.msg == "f");
381 assert(!e.next.next);
382 }
383 }
384
385 void bug1513c()
386 {
387 try
388 {
389 try
390 {
391 throw new Exception("a");
392 }
393 finally
394 {
395 result1513 |= 1;
396 throw new Exception("b");
397 }
398 }
399 finally
400 {
401 bug1513b();
402 result1513 |= 2;
403 throw new Exception("c");
404 }
405 }
406
407 void bug1513()
408 {
409 result1513 = 0;
410 try
411 {
412 bug1513c();
413 }
414 catch(Exception e)
415 {
416 assert(result1513 == 7);
417 assert(e.msg == "a");
418 assert(e.next.msg == "b");
419 assert(e.next.next.msg == "c");
420 }
421 }
422
423 void collideone()
424 {
425 try
426 {
427 throw new Exception("x");
428 }
429 finally
430 {
431 throw new Exception("y");
432 }
433 }
434
435 void doublecollide()
436 {
437 try
438 {
439 try
440 {
441 try
442 {
443 throw new Exception("p");
444 }
445 finally
446 {
447 throw new Exception("q");
448 }
449 }
450 finally
451 {
452 collideone();
453 }
454 }
455 catch(Exception e)
456 {
457 assert(e.msg == "p");
458 assert(e.next.msg == "q");
459 assert(e.next.next.msg == "x");
460 assert(e.next.next.next.msg == "y");
461 assert(!e.next.next.next.next);
462 }
463 }
464
465 void collidetwo()
466 {
467 try
468 {
469 try
470 {
471 throw new Exception("p2");
472 }
473 finally
474 {
475 throw new Exception("q2");
476 }
477 }
478 finally
479 {
480 collideone();
481 }
482 }
483
484 void collideMixed()
485 {
486 int works = 6;
487 try
488 {
489 try
490 {
491 try
492 {
493 throw new Exception("e");
494 }
495 finally
496 {
497 throw new Error("t");
498 }
499 }
500 catch(Exception f)
501 { // Doesn't catch, because Error is chained to it.
502 works += 2;
503 }
504 }
505 catch(Error z)
506 {
507 works += 4;
508 assert(z.msg=="t"); // Error comes first
509 assert(z.next is null);
510 assert(z.bypassedException.msg == "e");
511 }
512 assert(works == 10);
513 }
514
515 class AnotherException : Exception
516 {
517 this(string s)
518 {
519 super(s);
520 }
521 }
522
523 void multicollide()
524 {
525 try
526 {
527 try
528 {
529 try
530 {
531 try
532 {
533 throw new Exception("m2");
534 }
535 finally
536 {
537 throw new AnotherException("n2");
538 }
539 }
540 catch(AnotherException s)
541 { // Not caught -- we needed to catch the root cause "m2", not
542 // just the collateral "n2" (which would leave m2 uncaught).
543 assert(0);
544 }
545 }
546 finally
547 {
548 collidetwo();
549 }
550 }
551 catch(Exception f)
552 {
553 assert(f.msg == "m2");
554 assert(f.next.msg == "n2");
555 Throwable e = f.next.next;
556 assert(e.msg == "p2");
557 assert(e.next.msg == "q2");
558 assert(e.next.next.msg == "x");
559 assert(e.next.next.next.msg == "y");
560 assert(!e.next.next.next.next);
561 }
562 }
563
564 /****************************************************/
565
566 void use9568(char [] x, char [] y) {}
567
568 int bug9568()
569 {
570 try
571 return 7;
572 finally
573 use9568(null,null);
574 }
575
576 void test9568()
577 {
578 assert( bug9568() == 7 );
579 }
580
581 /****************************************************/
582
583 version (DigitalMars)
584 {
585 void test8a()
586 {
587 int a;
588 goto L2; // L2 is not addressable.
589
590 try {
591 a += 2;
592 }
593 catch (Exception) {
594 a += 3;
595 L2: ;
596 a += 100;
597 }
598 assert(a == 100);
599 }
600
601 void test8b()
602 {
603 int a;
604 goto L2; // L2 is not addressable.
605
606 try {
607 }
608 catch (Exception) {
609 a += 3;
610 L2: ;
611 a += 100;
612 }
613 assert(a == 100);
614 }
615
616 void test8c()
617 {
618 int a;
619 goto L2; // L2 is not addressable.
620
621 try
622 static assert(true);
623 catch (Exception) {
624 a += 3;
625 L2: ;
626 a += 100;
627 }
628 assert(a == 100);
629 }
630
631 void test8()
632 {
633 test8a();
634 test8b();
635 test8c();
636 }
637 }
638
639 /****************************************************/
640
641 uint foo9(uint i)
642 {
643 try
644 {
645 ++i;
646 return 3;
647 }
648 catch (Exception e)
649 {
650 debug printf("Exception happened\n");
651 }
652 return 4;
653 }
654
655 void test9()
656 {
657 assert(foo9(7) == 3);
658 }
659
660 /****************************************************/
661 // 10964
662
663 void test10964()
664 {
665 static struct S
666 {
667 this(this)
668 {
669 throw new Exception("BOOM!");
670 }
671 }
672
673 S ss;
674 S[1] sa;
675 int result;
676
677 result = 0;
678 try
679 {
680 ss = ss;
681 }
682 catch (Exception e) result = 1;
683 catch (Error e) result = 2;
684 catch (Throwable e) result = 3;
685 assert(result == 1);
686
687 try
688 {
689 sa = ss;
690 }
691 catch (Exception e) result = 1;
692 catch (Error e) result = 2;
693 catch (Throwable e) result = 3;
694 assert(result == 1);
695
696 try
697 {
698 sa = sa;
699 }
700 catch (Exception e) result = 1;
701 catch (Error e) result = 2;
702 catch (Throwable e) result = 3;
703 assert(result == 1);
704 }
705
706 /****************************************************/
707
708 alias Action = void delegate();
709
710 class A10
711 {
712 invariant()
713 {
714 }
715
716 public Action foo(Action a)
717 {
718 synchronized
719 {
720 B10 elements = new B10;
721 Action[] actions = [a];
722
723 elements.bar(actions);
724
725 if (actions.length > 1)
726 elements.bar(actions);
727 return actions[0];
728 }
729 return null;
730 }
731 }
732
733 class B10
734 {
735 public bool bar(ref Action[])
736 {
737 return false;
738 }
739 }
740
741 class D10
742 {
743 void baz()
744 {
745 }
746 }
747
748 void test12989()
749 {
750 auto a = new A10;
751 auto d = new D10;
752
753 assert(a.foo(&d.baz) == &d.baz);
754 }
755
756 /****************************************************/
757
758 int bar10(int c)
759 {
760 if (c <= 0xFFFF)
761 {
762 L3:
763 return 3;
764 }
765 throw new Exception("msg");
766 goto L3;
767 }
768
769 void test10()
770 {
771 int x;
772 try
773 {
774 bar10(0x110000);
775 }
776 catch (Exception e)
777 {
778 printf("caught\n");
779 x = 1;
780 }
781 assert(x == 1);
782 printf("test10 success\n");
783 }
784
785 /****************************************************/
786
787 class ParseException : Exception
788 {
789 @safe pure nothrow this( string msg )
790 {
791 super( msg );
792 }
793 }
794
795 class OverflowException : Exception
796 {
797 @safe pure nothrow this( string msg )
798 {
799 super( msg );
800 }
801 }
802
803 void test11()
804 {
805 int x;
806 try
807 {
808 printf("test11()\n");
809 throw new ParseException("msg");
810 }
811 catch( OverflowException e )
812 {
813 printf( "catch OverflowException\n" );
814 }
815 catch( ParseException e )
816 {
817 printf( "catch ParseException: %.*s\n", cast(int) e.msg.length, e.msg.ptr );
818 x = 1;
819 }
820 assert(x == 1);
821 }
822
823 /****************************************************/
824 // https://issues.dlang.org/show_bug.cgi?id=17481
825
826 class C17481
827 {
828 synchronized void trigger(){ new ubyte[1]; }
829 }
830
831 void test17481()
832 {
833 auto k = new shared C17481;
834 k.trigger;
835 }
836
837 /****************************************************/
838
839 int main()
840 {
841 printf("start\n");
842 foo(3);
843 test2();
844 test3();
845 test4();
846 test5();
847 test6();
848 test7();
849
850 bug1513();
851 doublecollide();
852 collideMixed();
853 multicollide();
854 test9568();
855
856 version(DigitalMars) test8();
857 test9();
858 test10964();
859 test12989();
860 test10();
861 test11();
862 test17481();
863
864 printf("finish\n");
865 return 0;
866 }