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