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