1*fe36f081STimo Kreuzer // Copyright (c) Microsoft. All rights reserved.
2*fe36f081STimo Kreuzer // Licensed under the MIT license. See LICENSE file in the project root for
3*fe36f081STimo Kreuzer // full license information.
4*fe36f081STimo Kreuzer 
5*fe36f081STimo Kreuzer /*
6*fe36f081STimo Kreuzer      Tests some throw and rethrow situations (mostly CRT a test)
7*fe36f081STimo Kreuzer */
8*fe36f081STimo Kreuzer 
9*fe36f081STimo Kreuzer 
10*fe36f081STimo Kreuzer #include <stdlib.h>
11*fe36f081STimo Kreuzer #include <stdio.h>
12*fe36f081STimo Kreuzer 
13*fe36f081STimo Kreuzer 
14*fe36f081STimo Kreuzer #define FALSE 0
15*fe36f081STimo Kreuzer #define TRUE 1
16*fe36f081STimo Kreuzer #define NO_CTOR_THROW 1
17*fe36f081STimo Kreuzer #define NO_DTOR_THROW 2
18*fe36f081STimo Kreuzer 
19*fe36f081STimo Kreuzer 
20*fe36f081STimo Kreuzer int Object[100];
21*fe36f081STimo Kreuzer int CurrentObjectNumber, Test;
22*fe36f081STimo Kreuzer int MaxTest = 10;
23*fe36f081STimo Kreuzer int MaxObjectCount = 1;
24*fe36f081STimo Kreuzer int Fail;
25*fe36f081STimo Kreuzer 
26*fe36f081STimo Kreuzer 
FAIL(int i)27*fe36f081STimo Kreuzer void FAIL(int i)
28*fe36f081STimo Kreuzer {
29*fe36f081STimo Kreuzer     printf("FAILED on %d\n", i);
30*fe36f081STimo Kreuzer     Fail++;
31*fe36f081STimo Kreuzer }
32*fe36f081STimo Kreuzer 
dealloc(int i,int no_throw)33*fe36f081STimo Kreuzer void dealloc(int i, int no_throw)
34*fe36f081STimo Kreuzer {
35*fe36f081STimo Kreuzer     /* Make sure i is valid, and object exists */
36*fe36f081STimo Kreuzer     if(i<0 || i>=MaxObjectCount || !Object[i])
37*fe36f081STimo Kreuzer         FAIL(i);
38*fe36f081STimo Kreuzer 
39*fe36f081STimo Kreuzer     Object[i] = 0;
40*fe36f081STimo Kreuzer }
41*fe36f081STimo Kreuzer 
alloc(int i,int no_throw)42*fe36f081STimo Kreuzer void alloc(int i, int no_throw)
43*fe36f081STimo Kreuzer {
44*fe36f081STimo Kreuzer     if(CurrentObjectNumber > MaxObjectCount)
45*fe36f081STimo Kreuzer         MaxObjectCount = CurrentObjectNumber;
46*fe36f081STimo Kreuzer 
47*fe36f081STimo Kreuzer     /* Object already exists? */
48*fe36f081STimo Kreuzer     if(Object[i]) FAIL(i);
49*fe36f081STimo Kreuzer 
50*fe36f081STimo Kreuzer     Object[i] = 1;
51*fe36f081STimo Kreuzer }
52*fe36f081STimo Kreuzer 
53*fe36f081STimo Kreuzer class B
54*fe36f081STimo Kreuzer {
55*fe36f081STimo Kreuzer public:
56*fe36f081STimo Kreuzer     int i;
57*fe36f081STimo Kreuzer     int flag;
58*fe36f081STimo Kreuzer     B();
59*fe36f081STimo Kreuzer     B(int);
60*fe36f081STimo Kreuzer     B(const B &b);
61*fe36f081STimo Kreuzer     ~B();
62*fe36f081STimo Kreuzer };
63*fe36f081STimo Kreuzer 
B()64*fe36f081STimo Kreuzer B::B()
65*fe36f081STimo Kreuzer {
66*fe36f081STimo Kreuzer     i = CurrentObjectNumber++;
67*fe36f081STimo Kreuzer     printf("B ctor.  i = %d\n", i);
68*fe36f081STimo Kreuzer     alloc(i, FALSE);
69*fe36f081STimo Kreuzer }
70*fe36f081STimo Kreuzer 
B(int f)71*fe36f081STimo Kreuzer B::B(int f)
72*fe36f081STimo Kreuzer {
73*fe36f081STimo Kreuzer     i = CurrentObjectNumber++;
74*fe36f081STimo Kreuzer     flag = f;
75*fe36f081STimo Kreuzer     printf("B ctor.  i = %d\n", i);
76*fe36f081STimo Kreuzer     alloc(i, flag==NO_CTOR_THROW);
77*fe36f081STimo Kreuzer }
78*fe36f081STimo Kreuzer 
B(const B & b)79*fe36f081STimo Kreuzer B::B(const B &b)
80*fe36f081STimo Kreuzer {
81*fe36f081STimo Kreuzer     i = CurrentObjectNumber++;
82*fe36f081STimo Kreuzer     printf("B copy ctor.  i = %d\n", i);
83*fe36f081STimo Kreuzer     alloc(i, FALSE);
84*fe36f081STimo Kreuzer }
85*fe36f081STimo Kreuzer 
~B()86*fe36f081STimo Kreuzer B::~B()
87*fe36f081STimo Kreuzer {
88*fe36f081STimo Kreuzer     printf("B dtor.  i = %d\n", i);
89*fe36f081STimo Kreuzer     dealloc(i, flag==NO_DTOR_THROW);
90*fe36f081STimo Kreuzer }
91*fe36f081STimo Kreuzer 
92*fe36f081STimo Kreuzer class A
93*fe36f081STimo Kreuzer {
94*fe36f081STimo Kreuzer public:
95*fe36f081STimo Kreuzer     int i;
96*fe36f081STimo Kreuzer     A();
A(int)97*fe36f081STimo Kreuzer     A(int)
98*fe36f081STimo Kreuzer     {
99*fe36f081STimo Kreuzer         i = CurrentObjectNumber++;
100*fe36f081STimo Kreuzer         printf("A(int) ctor.  i = %d\n", i);
101*fe36f081STimo Kreuzer         alloc(i, FALSE);
102*fe36f081STimo Kreuzer     }
103*fe36f081STimo Kreuzer     A operator+(A a);
A(const A & a)104*fe36f081STimo Kreuzer     A(const A &a)
105*fe36f081STimo Kreuzer     {
106*fe36f081STimo Kreuzer         /* Try objects in ctor */
107*fe36f081STimo Kreuzer         B b1 = NO_DTOR_THROW, b2 = NO_DTOR_THROW;
108*fe36f081STimo Kreuzer 
109*fe36f081STimo Kreuzer         i = CurrentObjectNumber++;
110*fe36f081STimo Kreuzer         printf("A copy ctor.  i = %d\n", i);
111*fe36f081STimo Kreuzer         alloc(i, FALSE);
112*fe36f081STimo Kreuzer     }
113*fe36f081STimo Kreuzer 
~A()114*fe36f081STimo Kreuzer     ~A(){
115*fe36f081STimo Kreuzer         /* Try objects in dtor */
116*fe36f081STimo Kreuzer         B b1 = NO_CTOR_THROW, b2 = NO_CTOR_THROW;
117*fe36f081STimo Kreuzer 
118*fe36f081STimo Kreuzer         printf("A dtor.  i = %d\n", i);
119*fe36f081STimo Kreuzer         dealloc(i, FALSE);
120*fe36f081STimo Kreuzer     };
121*fe36f081STimo Kreuzer };
122*fe36f081STimo Kreuzer 
A()123*fe36f081STimo Kreuzer A::A()
124*fe36f081STimo Kreuzer {
125*fe36f081STimo Kreuzer     i=CurrentObjectNumber++;
126*fe36f081STimo Kreuzer     printf("A ctor.  i = %d\n", i);
127*fe36f081STimo Kreuzer     alloc(i, FALSE);
128*fe36f081STimo Kreuzer }
129*fe36f081STimo Kreuzer 
operator +(A a)130*fe36f081STimo Kreuzer A A::operator+(A a)
131*fe36f081STimo Kreuzer {
132*fe36f081STimo Kreuzer     printf("A%d + A%d\n", i, a.i);
133*fe36f081STimo Kreuzer     return A();
134*fe36f081STimo Kreuzer }
135*fe36f081STimo Kreuzer 
Throwa(A a)136*fe36f081STimo Kreuzer void Throwa(A a)
137*fe36f081STimo Kreuzer {
138*fe36f081STimo Kreuzer     printf("Throwing\n");
139*fe36f081STimo Kreuzer     throw a;
140*fe36f081STimo Kreuzer }
141*fe36f081STimo Kreuzer 
bar()142*fe36f081STimo Kreuzer void bar()
143*fe36f081STimo Kreuzer {
144*fe36f081STimo Kreuzer     A a;
145*fe36f081STimo Kreuzer 
146*fe36f081STimo Kreuzer     Throwa(a);
147*fe36f081STimo Kreuzer }
148*fe36f081STimo Kreuzer 
foobar()149*fe36f081STimo Kreuzer void foobar()
150*fe36f081STimo Kreuzer {
151*fe36f081STimo Kreuzer     B b;
152*fe36f081STimo Kreuzer     bar();
153*fe36f081STimo Kreuzer }
154*fe36f081STimo Kreuzer 
155*fe36f081STimo Kreuzer // Somehow, inlining this causes different unwinding order..
156*fe36f081STimo Kreuzer 
Rethrow2()157*fe36f081STimo Kreuzer __declspec(noinline) void Rethrow2()
158*fe36f081STimo Kreuzer {
159*fe36f081STimo Kreuzer     A a;
160*fe36f081STimo Kreuzer     printf("Rethrowing\n");
161*fe36f081STimo Kreuzer     throw;
162*fe36f081STimo Kreuzer }
163*fe36f081STimo Kreuzer 
164*fe36f081STimo Kreuzer #pragma inline_depth(0)
Rethrow()165*fe36f081STimo Kreuzer void Rethrow()
166*fe36f081STimo Kreuzer {
167*fe36f081STimo Kreuzer     Rethrow2();
168*fe36f081STimo Kreuzer }
169*fe36f081STimo Kreuzer #pragma inline_depth()
170*fe36f081STimo Kreuzer 
foobar2()171*fe36f081STimo Kreuzer void foobar2()
172*fe36f081STimo Kreuzer {
173*fe36f081STimo Kreuzer     B b;
174*fe36f081STimo Kreuzer 
175*fe36f081STimo Kreuzer     try{
176*fe36f081STimo Kreuzer         A a;
177*fe36f081STimo Kreuzer         bar();
178*fe36f081STimo Kreuzer     }catch(A a){
179*fe36f081STimo Kreuzer         printf("In catch;\n");
180*fe36f081STimo Kreuzer         Rethrow();
181*fe36f081STimo Kreuzer     }
182*fe36f081STimo Kreuzer }
183*fe36f081STimo Kreuzer 
foobar3()184*fe36f081STimo Kreuzer void foobar3()
185*fe36f081STimo Kreuzer {
186*fe36f081STimo Kreuzer     B b;
187*fe36f081STimo Kreuzer 
188*fe36f081STimo Kreuzer     try{
189*fe36f081STimo Kreuzer         A a;
190*fe36f081STimo Kreuzer         bar();
191*fe36f081STimo Kreuzer     }catch(A a){
192*fe36f081STimo Kreuzer         printf("In catch\n");
193*fe36f081STimo Kreuzer         A a2;
194*fe36f081STimo Kreuzer 
195*fe36f081STimo Kreuzer         printf("Throwing new a\n");
196*fe36f081STimo Kreuzer         throw a2;
197*fe36f081STimo Kreuzer     }
198*fe36f081STimo Kreuzer }
199*fe36f081STimo Kreuzer 
foobar4()200*fe36f081STimo Kreuzer void foobar4()
201*fe36f081STimo Kreuzer {
202*fe36f081STimo Kreuzer     B b;
203*fe36f081STimo Kreuzer 
204*fe36f081STimo Kreuzer     try{
205*fe36f081STimo Kreuzer         B b;
206*fe36f081STimo Kreuzer         try{
207*fe36f081STimo Kreuzer             A a1, a2;
208*fe36f081STimo Kreuzer             try {
209*fe36f081STimo Kreuzer                 A a1, a2;
210*fe36f081STimo Kreuzer                 foobar2();
211*fe36f081STimo Kreuzer             }catch(A a){
212*fe36f081STimo Kreuzer                 printf("In catch #1\n");
213*fe36f081STimo Kreuzer                 B b;
214*fe36f081STimo Kreuzer                 printf("Rethrowing\n");
215*fe36f081STimo Kreuzer                 throw;
216*fe36f081STimo Kreuzer             }
217*fe36f081STimo Kreuzer         }catch(A &a){
218*fe36f081STimo Kreuzer             printf("In catch #2\n");
219*fe36f081STimo Kreuzer             A a2;
220*fe36f081STimo Kreuzer 
221*fe36f081STimo Kreuzer             printf("Throwing new a\n");
222*fe36f081STimo Kreuzer             throw a;
223*fe36f081STimo Kreuzer         }
224*fe36f081STimo Kreuzer     }catch(A a){
225*fe36f081STimo Kreuzer         printf("In catch #3\n");
226*fe36f081STimo Kreuzer         B b;
227*fe36f081STimo Kreuzer         printf("Rethrowing\n");
228*fe36f081STimo Kreuzer         throw;
229*fe36f081STimo Kreuzer     }
230*fe36f081STimo Kreuzer }
231*fe36f081STimo Kreuzer 
throw_B_2()232*fe36f081STimo Kreuzer __declspec(noinline) void throw_B_2()
233*fe36f081STimo Kreuzer {
234*fe36f081STimo Kreuzer     B b;
235*fe36f081STimo Kreuzer     printf("Throwing a new b\n");
236*fe36f081STimo Kreuzer     throw b;
237*fe36f081STimo Kreuzer }
238*fe36f081STimo Kreuzer 
239*fe36f081STimo Kreuzer #pragma inline_depth(0)
throw_B()240*fe36f081STimo Kreuzer void throw_B()
241*fe36f081STimo Kreuzer {
242*fe36f081STimo Kreuzer     throw_B_2();
243*fe36f081STimo Kreuzer }
244*fe36f081STimo Kreuzer #pragma inline_depth()
245*fe36f081STimo Kreuzer 
246*fe36f081STimo Kreuzer 
foobar5()247*fe36f081STimo Kreuzer void foobar5()
248*fe36f081STimo Kreuzer {
249*fe36f081STimo Kreuzer     try {
250*fe36f081STimo Kreuzer         B b1;
251*fe36f081STimo Kreuzer         try {
252*fe36f081STimo Kreuzer             B b2;
253*fe36f081STimo Kreuzer             try {
254*fe36f081STimo Kreuzer                 B b3;
255*fe36f081STimo Kreuzer                 foobar();
256*fe36f081STimo Kreuzer             }catch(B b){
257*fe36f081STimo Kreuzer                 printf("In catch #1\n");
258*fe36f081STimo Kreuzer                 FAIL(-1);
259*fe36f081STimo Kreuzer             }
260*fe36f081STimo Kreuzer             FAIL(-1);
261*fe36f081STimo Kreuzer         }catch(A a){
262*fe36f081STimo Kreuzer             A a2;
263*fe36f081STimo Kreuzer             printf("In catch #2\n");
264*fe36f081STimo Kreuzer             throw_B();
265*fe36f081STimo Kreuzer         }
266*fe36f081STimo Kreuzer         FAIL(-1);
267*fe36f081STimo Kreuzer     }catch(B b){
268*fe36f081STimo Kreuzer         printf("In catch #3\n");
269*fe36f081STimo Kreuzer         printf("Throwing a new a\n");
270*fe36f081STimo Kreuzer         throw A();
271*fe36f081STimo Kreuzer     }
272*fe36f081STimo Kreuzer     FAIL(-1);
273*fe36f081STimo Kreuzer }
274*fe36f081STimo Kreuzer 
275*fe36f081STimo Kreuzer 
276*fe36f081STimo Kreuzer /* Simple throw with unwinds */
test1()277*fe36f081STimo Kreuzer void test1()
278*fe36f081STimo Kreuzer {
279*fe36f081STimo Kreuzer     A a;
280*fe36f081STimo Kreuzer     foobar();
281*fe36f081STimo Kreuzer }
282*fe36f081STimo Kreuzer 
283*fe36f081STimo Kreuzer /* Throw followed by a rethrow */
test2()284*fe36f081STimo Kreuzer void test2()
285*fe36f081STimo Kreuzer {
286*fe36f081STimo Kreuzer     A a;
287*fe36f081STimo Kreuzer     foobar2();
288*fe36f081STimo Kreuzer }
289*fe36f081STimo Kreuzer 
290*fe36f081STimo Kreuzer /* Throw followed by a new throw */
test3()291*fe36f081STimo Kreuzer void test3()
292*fe36f081STimo Kreuzer {
293*fe36f081STimo Kreuzer     A a;
294*fe36f081STimo Kreuzer     foobar3();
295*fe36f081STimo Kreuzer }
296*fe36f081STimo Kreuzer 
297*fe36f081STimo Kreuzer /* Nested trys with rethrow/throw/rethrow */
test4()298*fe36f081STimo Kreuzer void test4()
299*fe36f081STimo Kreuzer {
300*fe36f081STimo Kreuzer     A a;
301*fe36f081STimo Kreuzer     foobar4();
302*fe36f081STimo Kreuzer }
303*fe36f081STimo Kreuzer 
304*fe36f081STimo Kreuzer /* Makes sure a new throw skips appropriate unwound frames. */
test5()305*fe36f081STimo Kreuzer void test5()
306*fe36f081STimo Kreuzer {
307*fe36f081STimo Kreuzer     A a;
308*fe36f081STimo Kreuzer     foobar5();
309*fe36f081STimo Kreuzer }
310*fe36f081STimo Kreuzer 
311*fe36f081STimo Kreuzer // Tests 3 level of new throw
test6()312*fe36f081STimo Kreuzer void test6()
313*fe36f081STimo Kreuzer {
314*fe36f081STimo Kreuzer     try{
315*fe36f081STimo Kreuzer         B b1;
316*fe36f081STimo Kreuzer         try{
317*fe36f081STimo Kreuzer             B b2;
318*fe36f081STimo Kreuzer             try{
319*fe36f081STimo Kreuzer                 B b3;
320*fe36f081STimo Kreuzer                 printf("Throwing a b\n");
321*fe36f081STimo Kreuzer                 throw(b3);
322*fe36f081STimo Kreuzer             }catch(B b){
323*fe36f081STimo Kreuzer                 B b4;
324*fe36f081STimo Kreuzer                 printf("In catch #1\n");
325*fe36f081STimo Kreuzer                 printf("Throwing a new b\n");
326*fe36f081STimo Kreuzer                 throw(b4);
327*fe36f081STimo Kreuzer             }
328*fe36f081STimo Kreuzer             FAIL(-1);
329*fe36f081STimo Kreuzer         }catch(B b){
330*fe36f081STimo Kreuzer             B b5;
331*fe36f081STimo Kreuzer             printf("In catch #2\n");
332*fe36f081STimo Kreuzer             printf("Throwing a new b\n");
333*fe36f081STimo Kreuzer             throw(b5);
334*fe36f081STimo Kreuzer         }
335*fe36f081STimo Kreuzer         FAIL(-1);
336*fe36f081STimo Kreuzer     }catch(B b){
337*fe36f081STimo Kreuzer         A a1;
338*fe36f081STimo Kreuzer         printf("In catch #3\n");
339*fe36f081STimo Kreuzer         printf("Throwing a new a\n");
340*fe36f081STimo Kreuzer         throw(a1);
341*fe36f081STimo Kreuzer     }
342*fe36f081STimo Kreuzer     FAIL(-1);
343*fe36f081STimo Kreuzer }
344*fe36f081STimo Kreuzer 
345*fe36f081STimo Kreuzer // Testing try/catch inside a catch
test7()346*fe36f081STimo Kreuzer void test7()
347*fe36f081STimo Kreuzer {
348*fe36f081STimo Kreuzer     B b1;
349*fe36f081STimo Kreuzer     try{
350*fe36f081STimo Kreuzer         B b2;
351*fe36f081STimo Kreuzer         try{
352*fe36f081STimo Kreuzer             B b3;
353*fe36f081STimo Kreuzer 
354*fe36f081STimo Kreuzer             printf("Throwing a b\n");
355*fe36f081STimo Kreuzer             throw(B());
356*fe36f081STimo Kreuzer         }catch(B b){
357*fe36f081STimo Kreuzer             B b4;
358*fe36f081STimo Kreuzer             printf("In catch #1\n");
359*fe36f081STimo Kreuzer             try{
360*fe36f081STimo Kreuzer                 B b5;
361*fe36f081STimo Kreuzer                 printf("Rethrowing b\n");
362*fe36f081STimo Kreuzer                 throw;
363*fe36f081STimo Kreuzer             }catch(B b){
364*fe36f081STimo Kreuzer                 B b5;
365*fe36f081STimo Kreuzer                 printf("In catch #1 of catch#1\n");
366*fe36f081STimo Kreuzer                 printf("Rethrowing b\n");
367*fe36f081STimo Kreuzer                 throw;
368*fe36f081STimo Kreuzer             }
369*fe36f081STimo Kreuzer         }
370*fe36f081STimo Kreuzer     }catch(B b){
371*fe36f081STimo Kreuzer         B b6;
372*fe36f081STimo Kreuzer         printf("In catch #2\n");
373*fe36f081STimo Kreuzer         printf("Throwing a new A\n");
374*fe36f081STimo Kreuzer         throw(A());
375*fe36f081STimo Kreuzer     }
376*fe36f081STimo Kreuzer }
377*fe36f081STimo Kreuzer 
ThrowB()378*fe36f081STimo Kreuzer void ThrowB()
379*fe36f081STimo Kreuzer {
380*fe36f081STimo Kreuzer     B b;
381*fe36f081STimo Kreuzer 
382*fe36f081STimo Kreuzer     throw(B());
383*fe36f081STimo Kreuzer }
384*fe36f081STimo Kreuzer 
bar8()385*fe36f081STimo Kreuzer void bar8()
386*fe36f081STimo Kreuzer {
387*fe36f081STimo Kreuzer     try{
388*fe36f081STimo Kreuzer         B b5;
389*fe36f081STimo Kreuzer         printf("Rethrowing b\n");
390*fe36f081STimo Kreuzer         Rethrow();
391*fe36f081STimo Kreuzer     }catch(B b){
392*fe36f081STimo Kreuzer         B b5;
393*fe36f081STimo Kreuzer         printf("In catch #1 of catch#1\n");
394*fe36f081STimo Kreuzer         printf("Rethrowing b\n");
395*fe36f081STimo Kreuzer         Rethrow();
396*fe36f081STimo Kreuzer     }
397*fe36f081STimo Kreuzer }
398*fe36f081STimo Kreuzer 
foo8()399*fe36f081STimo Kreuzer void foo8()
400*fe36f081STimo Kreuzer {
401*fe36f081STimo Kreuzer     B b;
402*fe36f081STimo Kreuzer     try{
403*fe36f081STimo Kreuzer         B b3;
404*fe36f081STimo Kreuzer 
405*fe36f081STimo Kreuzer         printf("Throwing a b\n");
406*fe36f081STimo Kreuzer         ThrowB();
407*fe36f081STimo Kreuzer     }catch(B b){
408*fe36f081STimo Kreuzer         B b4;
409*fe36f081STimo Kreuzer         printf("In catch #1\n");
410*fe36f081STimo Kreuzer         bar8();
411*fe36f081STimo Kreuzer     }
412*fe36f081STimo Kreuzer }
413*fe36f081STimo Kreuzer 
414*fe36f081STimo Kreuzer // Testing call to try/catch function inside a catch
test8()415*fe36f081STimo Kreuzer void test8()
416*fe36f081STimo Kreuzer {
417*fe36f081STimo Kreuzer     B b1;
418*fe36f081STimo Kreuzer     try{
419*fe36f081STimo Kreuzer         B b2;
420*fe36f081STimo Kreuzer         foo8();
421*fe36f081STimo Kreuzer     }catch(B b){
422*fe36f081STimo Kreuzer         B b6;
423*fe36f081STimo Kreuzer         printf("In catch #2\n");
424*fe36f081STimo Kreuzer         printf("Throwing a new A\n");
425*fe36f081STimo Kreuzer         throw(A());
426*fe36f081STimo Kreuzer     }
427*fe36f081STimo Kreuzer }
428*fe36f081STimo Kreuzer 
foo9()429*fe36f081STimo Kreuzer void foo9()
430*fe36f081STimo Kreuzer {
431*fe36f081STimo Kreuzer     try {
432*fe36f081STimo Kreuzer         puts("Rethrow");
433*fe36f081STimo Kreuzer         throw;
434*fe36f081STimo Kreuzer     }catch(...){
435*fe36f081STimo Kreuzer         puts("In catch #2");
436*fe36f081STimo Kreuzer     }
437*fe36f081STimo Kreuzer }
438*fe36f081STimo Kreuzer 
test9()439*fe36f081STimo Kreuzer void test9()
440*fe36f081STimo Kreuzer {
441*fe36f081STimo Kreuzer     try{
442*fe36f081STimo Kreuzer         B b;
443*fe36f081STimo Kreuzer         puts("Throwing B");
444*fe36f081STimo Kreuzer         throw b;
445*fe36f081STimo Kreuzer     }catch(...){
446*fe36f081STimo Kreuzer         puts("In catch #1");
447*fe36f081STimo Kreuzer         foo9();
448*fe36f081STimo Kreuzer     }
449*fe36f081STimo Kreuzer     puts("End of test9, throwing a A");
450*fe36f081STimo Kreuzer     throw A();
451*fe36f081STimo Kreuzer }
452*fe36f081STimo Kreuzer 
foo10()453*fe36f081STimo Kreuzer void foo10()
454*fe36f081STimo Kreuzer {
455*fe36f081STimo Kreuzer     try {
456*fe36f081STimo Kreuzer         puts("Throwing a new B()");
457*fe36f081STimo Kreuzer         throw B();
458*fe36f081STimo Kreuzer     }catch(...){
459*fe36f081STimo Kreuzer         puts("In catch #2");
460*fe36f081STimo Kreuzer     }
461*fe36f081STimo Kreuzer }
462*fe36f081STimo Kreuzer 
test10()463*fe36f081STimo Kreuzer void test10()
464*fe36f081STimo Kreuzer {
465*fe36f081STimo Kreuzer     try{
466*fe36f081STimo Kreuzer         B b;
467*fe36f081STimo Kreuzer         puts("Throwing B");
468*fe36f081STimo Kreuzer         throw b;
469*fe36f081STimo Kreuzer     }catch(...){
470*fe36f081STimo Kreuzer         puts("In catch #1");
471*fe36f081STimo Kreuzer         foo10();
472*fe36f081STimo Kreuzer     }
473*fe36f081STimo Kreuzer     puts("End of test10, throwing a A");
474*fe36f081STimo Kreuzer     throw A();
475*fe36f081STimo Kreuzer }
476*fe36f081STimo Kreuzer 
main()477*fe36f081STimo Kreuzer int main()
478*fe36f081STimo Kreuzer {
479*fe36f081STimo Kreuzer     int i;
480*fe36f081STimo Kreuzer 
481*fe36f081STimo Kreuzer     /* Call test(), with a different ctor/dtor throwing each time */
482*fe36f081STimo Kreuzer     for(Test = 1; Test <= MaxTest; Test++)  {
483*fe36f081STimo Kreuzer 
484*fe36f081STimo Kreuzer         CurrentObjectNumber = 0;
485*fe36f081STimo Kreuzer 
486*fe36f081STimo Kreuzer         printf("\nTest #%d\n", Test);
487*fe36f081STimo Kreuzer 
488*fe36f081STimo Kreuzer         try {
489*fe36f081STimo Kreuzer             switch(Test){
490*fe36f081STimo Kreuzer             case 1:
491*fe36f081STimo Kreuzer                 test1();
492*fe36f081STimo Kreuzer                 break;
493*fe36f081STimo Kreuzer             case 2:
494*fe36f081STimo Kreuzer                 test2();
495*fe36f081STimo Kreuzer                 break;
496*fe36f081STimo Kreuzer             case 3:
497*fe36f081STimo Kreuzer                 test3();
498*fe36f081STimo Kreuzer                 break;
499*fe36f081STimo Kreuzer             case 4:
500*fe36f081STimo Kreuzer                 test4();
501*fe36f081STimo Kreuzer                 break;
502*fe36f081STimo Kreuzer             case 5:
503*fe36f081STimo Kreuzer                 test5();
504*fe36f081STimo Kreuzer                 break;
505*fe36f081STimo Kreuzer             case 6:
506*fe36f081STimo Kreuzer                 test6();
507*fe36f081STimo Kreuzer                 break;
508*fe36f081STimo Kreuzer             case 7:
509*fe36f081STimo Kreuzer                 test7();
510*fe36f081STimo Kreuzer                 break;
511*fe36f081STimo Kreuzer             case 8:
512*fe36f081STimo Kreuzer                 test8();
513*fe36f081STimo Kreuzer                 break;
514*fe36f081STimo Kreuzer             case 9:
515*fe36f081STimo Kreuzer                 test9();
516*fe36f081STimo Kreuzer                 break;
517*fe36f081STimo Kreuzer             case 10:
518*fe36f081STimo Kreuzer                 test10();
519*fe36f081STimo Kreuzer                 break;
520*fe36f081STimo Kreuzer             }
521*fe36f081STimo Kreuzer 
522*fe36f081STimo Kreuzer             FAIL(-1);
523*fe36f081STimo Kreuzer 
524*fe36f081STimo Kreuzer         }catch(A a){
525*fe36f081STimo Kreuzer             printf("In main's catch\n");
526*fe36f081STimo Kreuzer         }catch(...){
527*fe36f081STimo Kreuzer             FAIL(-1);
528*fe36f081STimo Kreuzer         }
529*fe36f081STimo Kreuzer 
530*fe36f081STimo Kreuzer         /* Any objects which didn't get dtor'd? */
531*fe36f081STimo Kreuzer         for(i = 0; i < MaxObjectCount; i++) {
532*fe36f081STimo Kreuzer             if(Object[i]) {
533*fe36f081STimo Kreuzer                 FAIL(i);
534*fe36f081STimo Kreuzer                 Object[i] = 0;
535*fe36f081STimo Kreuzer             }
536*fe36f081STimo Kreuzer         }
537*fe36f081STimo Kreuzer 
538*fe36f081STimo Kreuzer         printf("\n");
539*fe36f081STimo Kreuzer     }
540*fe36f081STimo Kreuzer 
541*fe36f081STimo Kreuzer     printf("\n");
542*fe36f081STimo Kreuzer     if(Fail)
543*fe36f081STimo Kreuzer         printf("FAILED %d tests\n", Fail);
544*fe36f081STimo Kreuzer     else
545*fe36f081STimo Kreuzer         printf("Passed\n");
546*fe36f081STimo Kreuzer 
547*fe36f081STimo Kreuzer }
548