xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/testsuite/libphobos.exceptions/catch_in_finally.d (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 import core.stdc.stdio : fprintf, stderr;
2 
3 class MyException : Exception
4 {
this()5     this() { super(typeof(this).stringof); }
6 }
7 
throw_catch()8 void throw_catch()
9 {
10     try
11     {
12         throw new MyException;
13     }
14     catch (MyException)
15     {
16     }
17     catch (Exception)
18     {
19         assert(false);
20     }
21 }
22 
23 // Test that exceptions that are entirely thrown and caught in finally blocks don't affect exception handling.
test1()24 void test1()
25 {
26     try
27     {
28         try
29         {
30             throw new Exception("p");
31         }
32         finally
33         {
34             throw_catch();
35         }
36     }
37     catch (Exception e)
38     {
39         assert(e.msg == "p");
40     }
41 }
42 
43 // Test that exceptions that are entirely thrown and caught in finally blocks don't interfere with chaining.
test2()44 void test2()
45 {
46     try
47     {
48         try
49         {
50             try
51             {
52                 throw new Exception("p");
53             }
54             finally
55             {
56                 throw new Exception("q");
57             }
58         }
59         finally
60         {
61             throw_catch();
62         }
63     }
64     catch(Exception e)
65     {
66         assert(e.msg == "p");
67         assert(e.next.msg == "q");
68         assert(!e.next.next);
69     }
70 }
71 
test3()72 void test3()
73 {
74     try
75     {
76         try
77         {
78             try
79             {
80                 throw new Exception("p");
81             }
82             finally
83             {
84                 throw_catch();
85             }
86         }
87         finally
88         {
89             throw new Exception("q");
90         }
91     }
92     catch(Exception e)
93     {
94         assert(e.msg == "p");
95         assert(e.next.msg == "q");
96         assert(!e.next.next);
97     }
98 }
99 
100 // Test order of exception handler operations.
test4()101 void test4()
102 {
103     string result;
104     void throw_catch()
105     {
106         pragma(inline, false);
107         try
108         {
109             result ~= "b";
110             throw new MyException;
111         }
112         catch (MyException)
113         {
114             result ~= "c";
115         }
116         catch (Exception)
117         {
118             assert(false);
119         }
120     }
121     try
122     {
123         try
124         {
125             result ~= "a";
126             throw new Exception("");
127         }
128         finally
129         {
130             throw_catch();
131         }
132     }
133     catch(Exception e)
134     {
135         result ~= "d";
136     }
137     assert(result == "abcd");
138 }
139 
test5()140 void test5()
141 {
142     string result;
143     void fail()
144     {
145         result ~= "b";
146         throw new Exception("a");
147     }
148 
149     void throw_catch()
150     {
151         pragma(inline, false);
152         try
153         {
154             fail();
155         }
156         catch(Exception e)
157         {
158             assert(e.msg == "a");
159             assert(!e.next);
160             result ~= "c";
161         }
162     }
163     try
164     {
165         try
166         {
167             result ~= "a";
168             throw new Exception("x");
169         }
170         finally
171         {
172             throw_catch();
173         }
174     }
175     catch (Exception e)
176     {
177         assert(e.msg == "x");
178         assert(!e.next);
179         result ~= "d";
180     }
181     assert(result == "abcd");
182 }
183 
main()184 void main() {
185     test1();
186     test2();
187     test3();
188     test4();
189     test5();
190     fprintf(stderr, "success.\n");
191 }
192