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