1 // Copyright (C) 1999, 2000 Free Software Foundation, Inc.
2 // Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org>
3 
4 // We cannot catch an ambiguous base class. Check with a virtual
5 // polymorphic public DAG.
6 // -- public, << private, == virtual
7 
8 // D--B==A
9 // +--C==A
10 
11 // Special g++ Options: -w
12 
~AA13 struct A { int m; virtual ~A(){}};
14 struct B : virtual A { int m; };
15 struct C : virtual A { int m; };
16 struct D : B, C { int m; };
17 
fna(A * obj)18 void fna(A *obj) { throw obj; }
fnb(B * obj)19 void fnb(B *obj) { throw obj; }
fnc(C * obj)20 void fnc(C *obj) { throw obj; }
fnd(D * obj)21 void fnd(D *obj) { throw obj; }
22 
23 extern "C" void abort();
24 
check(D * d)25 void check(D *d)
26 {
27   int caught;
28 
29   // try with whole object
30   caught = 0;
31   try { fnd(d); }
32   catch(A *p) { caught = 1; if (p != d) abort();}
33   catch(...) { abort(); }
34   if (!caught) abort();
35 
36   caught = 0;
37   try { fnd(d); }
38   catch(B *p) { caught = 1; if (p != d) abort();}
39   catch(...) { abort(); }
40   if (!caught) abort();
41 
42   caught = 0;
43   try { fnd(d); }
44   catch(C *p) { caught = 1; if (p != d) abort();}
45   catch(...) { abort(); }
46   if (!caught) abort();
47 
48   // try with an A object
49   caught = 0;
50   try { fna((B *)d); }
51   catch(B *p) { abort(); } // throw type is static type
52   catch(A *p) { caught = 1; if (p != d) abort();}
53   catch(...) { abort(); }
54   if (!caught) abort();
55 
56   caught = 0;
57   try { fna((C *)d); }
58   catch(C *p) { abort(); } // throw type is static type
59   catch(A *p) { caught = 1; if (p != d) abort();}
60   catch(...) { abort(); }
61   if (!caught) abort();
62 
63   // try with B object
64   caught = 0;
65   try { fnb((B *)d); }
66   catch(A *p) { caught = 1; if (p != d) abort();}
67   catch(...) { abort(); }
68   if (!caught) abort();
69 
70   caught = 0;
71   try { fnb((B *)d); }
72   catch(B *p) { caught = 1; if (p != d) abort();}
73   catch(...) { abort(); }
74   if (!caught) abort();
75 
76   caught = 0;
77   try { fnb((B *)d); }
78   catch(C *p) { abort(); }
79   catch(D *p) { abort(); }
80   catch(...) { caught =1; }
81   if (!caught) abort();
82 
83   // try with C object
84   caught = 0;
85   try { fnc((C *)d); }
86   catch(A *p) { caught = 1; if (p != d) abort();}
87   catch(...) { abort(); }
88   if (!caught) abort();
89 
90   caught = 0;
91   try { fnc((C *)d); }
92   catch(C *p) { caught = 1; if (p != d) abort();}
93   catch(...) { abort(); }
94   if (!caught) abort();
95 
96   caught = 0;
97   try { fnc((C *)d); }
98   catch(B *p) { abort(); }
99   catch(D *p) { abort(); }
100   catch(...) { caught =1; }
101   if (!caught) abort();
102 
103   return;
104 }
105 
main()106 int main ()
107 {
108   D d;
109   check (&d); // try with an object
110   check ((D *)0); // try with no object
111 
112   return 0;
113 }
114