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.
5*c87b03e5Sespie // -- public, << private, == virtual
6*c87b03e5Sespie 
7*c87b03e5Sespie // D==B--A
8*c87b03e5Sespie // +==C--A
9*c87b03e5Sespie 
10*c87b03e5Sespie // Special g++ Options: -w
11*c87b03e5Sespie 
~AA12*c87b03e5Sespie struct A { int m; virtual ~A(){}};
13*c87b03e5Sespie struct B : A { int m; };
14*c87b03e5Sespie struct C : A { int m; };
15*c87b03e5Sespie struct D : virtual B, virtual C { int m; };
16*c87b03e5Sespie 
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) { abort(); } // A is ambiguous
33*c87b03e5Sespie   catch(D *p) { caught = 1; if (p != d) abort();}
34*c87b03e5Sespie   catch(...) { abort(); }
35*c87b03e5Sespie   if (!caught) abort();
36*c87b03e5Sespie 
37*c87b03e5Sespie   caught = 0;
38*c87b03e5Sespie   try { fnd(d); }
39*c87b03e5Sespie   catch(A *p) { abort(); } // A is ambiguous
40*c87b03e5Sespie   catch(B *p) { caught = 1; if (p != d) abort();}
41*c87b03e5Sespie   catch(...) { abort(); }
42*c87b03e5Sespie   if (!caught) abort();
43*c87b03e5Sespie 
44*c87b03e5Sespie   caught = 0;
45*c87b03e5Sespie   try { fnd(d); }
46*c87b03e5Sespie   catch(A *p) { abort(); } // A is ambiguous
47*c87b03e5Sespie   catch(C *p) { caught = 1; if (p != d) abort();}
48*c87b03e5Sespie   catch(...) { abort(); }
49*c87b03e5Sespie   if (!caught) abort();
50*c87b03e5Sespie 
51*c87b03e5Sespie   // try with an A object
52*c87b03e5Sespie   caught = 0;
53*c87b03e5Sespie   try { fna((B *)d); }
54*c87b03e5Sespie   catch(B *p) { abort(); } // throw type is static type
55*c87b03e5Sespie   catch(A *p) { caught = 1; if (p != (B *)d) abort();}
56*c87b03e5Sespie   catch(...) { abort(); }
57*c87b03e5Sespie   if (!caught) abort();
58*c87b03e5Sespie 
59*c87b03e5Sespie   caught = 0;
60*c87b03e5Sespie   try { fna((C *)d); }
61*c87b03e5Sespie   catch(C *p) { abort(); } // throw type is static type
62*c87b03e5Sespie   catch(A *p) { caught = 1; if (p != (C *)d) abort();}
63*c87b03e5Sespie   catch(...) { abort(); }
64*c87b03e5Sespie   if (!caught) abort();
65*c87b03e5Sespie 
66*c87b03e5Sespie   // try with B object
67*c87b03e5Sespie   caught = 0;
68*c87b03e5Sespie   try { fnb((B *)d); }
69*c87b03e5Sespie   catch(A *p) { caught = 1; if (p != (B *)d) abort();}
70*c87b03e5Sespie   catch(...) { abort(); }
71*c87b03e5Sespie   if (!caught) abort();
72*c87b03e5Sespie 
73*c87b03e5Sespie   caught = 0;
74*c87b03e5Sespie   try { fnb((B *)d); }
75*c87b03e5Sespie   catch(B *p) { caught = 1; if (p != d) abort();}
76*c87b03e5Sespie   catch(...) { abort(); }
77*c87b03e5Sespie   if (!caught) abort();
78*c87b03e5Sespie 
79*c87b03e5Sespie   caught = 0;
80*c87b03e5Sespie   try { fnb((B *)d); }
81*c87b03e5Sespie   catch(C *p) { abort(); }
82*c87b03e5Sespie   catch(D *p) { abort(); }
83*c87b03e5Sespie   catch(...) { caught =1; }
84*c87b03e5Sespie   if (!caught) abort();
85*c87b03e5Sespie 
86*c87b03e5Sespie   // try with C object
87*c87b03e5Sespie   caught = 0;
88*c87b03e5Sespie   try { fnc((C *)d); }
89*c87b03e5Sespie   catch(A *p) { caught = 1; if (p != (C *)d) abort();}
90*c87b03e5Sespie   catch(...) { abort(); }
91*c87b03e5Sespie   if (!caught) abort();
92*c87b03e5Sespie 
93*c87b03e5Sespie   caught = 0;
94*c87b03e5Sespie   try { fnc((C *)d); }
95*c87b03e5Sespie   catch(C *p) { caught = 1; if (p != d) abort();}
96*c87b03e5Sespie   catch(...) { abort(); }
97*c87b03e5Sespie   if (!caught) abort();
98*c87b03e5Sespie 
99*c87b03e5Sespie   caught = 0;
100*c87b03e5Sespie   try { fnc((C *)d); }
101*c87b03e5Sespie   catch(B *p) { abort(); }
102*c87b03e5Sespie   catch(D *p) { abort(); }
103*c87b03e5Sespie   catch(...) { caught =1; }
104*c87b03e5Sespie   if (!caught) abort();
105*c87b03e5Sespie 
106*c87b03e5Sespie   return;
107*c87b03e5Sespie }
108*c87b03e5Sespie 
main()109*c87b03e5Sespie int main ()
110*c87b03e5Sespie {
111*c87b03e5Sespie   D d;
112*c87b03e5Sespie   check (&d); // try with an object
113*c87b03e5Sespie   check ((D *)0); // try with no object
114*c87b03e5Sespie 
115*c87b03e5Sespie   return 0;
116*c87b03e5Sespie }
117