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