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.
7// -- public, << private, == virtual
8
9// E==D--B==A
10//    +--C==A
11//    +--AA-A
12
13
14struct A { int m; virtual ~A(){}};
15struct B : virtual A { int m; };
16struct C : virtual A { int m; };
17struct AA : A { int m; };
18struct D : B, C, AA { int m; };
19struct E : virtual D { int m; };
20
21void fna(A *obj) { throw obj; }
22void fnb(B *obj) { throw obj; }
23void fnc(C *obj) { throw obj; }
24void fnd(D *obj) { throw obj; }
25void fnaa(AA *obj) { throw obj; }
26void fne(E *obj) { throw obj; }
27
28extern "C" void abort();
29
30void check(E *e)
31{
32  int caught;
33
34  // try with whole object
35  caught = 0;
36  try { fne(e); }
37  catch(A *p) { abort(); } // A is ambiguous
38  catch(D *p) { caught = 1; if (p != e) abort();}
39  catch(...) { abort(); }
40  if (!caught) abort();
41
42  caught = 0;
43  try { fne(e); }
44  catch(A *p) { abort(); } // A is ambiguous
45  catch(B *p) { caught = 1; if (p != e) abort();}
46  catch(...) { abort(); }
47  if (!caught) abort();
48
49  caught = 0;
50  try { fne(e); }
51  catch(A *p) { abort(); } // A is ambiguous
52  catch(C *p) { caught = 1; if (p != e) abort();}
53  catch(...) { abort(); }
54  if (!caught) abort();
55
56  caught = 0;
57  try { fne(e); }
58  catch(A *p) { abort(); } // A is ambiguous
59  catch(AA *p) { caught = 1; if (p != e) abort();}
60  catch(...) { abort(); }
61  if (!caught) abort();
62
63  // try with D oject
64  caught = 0;
65  try { fnd((D *)e); }
66  catch(A *p) { abort(); } // A is ambiguous
67  catch(D *p) { caught = 1; if (p != e) abort();}
68  catch(...) { abort(); }
69  if (!caught) abort();
70
71  caught = 0;
72  try { fnd((D *)e); }
73  catch(A *p) { abort(); } // A is ambiguous
74  catch(B *p) { caught = 1; if (p != e) abort();}
75  catch(...) { abort(); }
76  if (!caught) abort();
77
78  caught = 0;
79  try { fnd((D *)e); }
80  catch(A *p) { abort(); } // A is ambiguous
81  catch(C *p) { caught = 1; if (p != e) abort();}
82  catch(...) { abort(); }
83  if (!caught) abort();
84
85  caught = 0;
86  try { fnd((D *)e); }
87  catch(A *p) { abort(); } // A is ambiguous
88  catch(AA *p) { caught = 1; if (p != e) abort();}
89  catch(...) { abort(); }
90  if (!caught) abort();
91
92  // try with an A object
93  caught = 0;
94  try { fna((B *)e); }
95  catch(B *p) { abort(); } // throw type is static type
96  catch(A *p) { caught = 1; if (p != (B *)e) abort();}
97  catch(...) { abort(); }
98  if (!caught) abort();
99
100  caught = 0;
101  try { fna((C *)e); }
102  catch(C *p) { abort(); } // throw type is static type
103  catch(A *p) { caught = 1; if (p != (C *)e) abort();}
104  catch(...) { abort(); }
105  if (!caught) abort();
106
107  caught = 0;
108  try { fna((AA *)e); }
109  catch(AA *p) { abort(); } // throw type is static type
110  catch(A *p) { caught = 1; if (p != (AA *)e) abort();}
111  catch(...) { abort(); }
112  if (!caught) abort();
113
114  // try with B object
115  caught = 0;
116  try { fnb((B *)e); }
117  catch(A *p) { caught = 1; if (p != (B *)e) abort();}
118  catch(...) { abort(); }
119  if (!caught) abort();
120
121  caught = 0;
122  try { fnb((B *)e); }
123  catch(B *p) { caught = 1; if (p != e) abort();}
124  catch(...) { abort(); }
125  if (!caught) abort();
126
127  caught = 0;
128  try { fnb((B *)e); }
129  catch(C *p) { abort(); }
130  catch(D *p) { abort(); }
131  catch(...) { caught =1; }
132  if (!caught) abort();
133
134  // try with C object
135  caught = 0;
136  try { fnc((C *)e); }
137  catch(A *p) { caught = 1; if (p != (C *)e) abort();}
138  catch(...) { abort(); }
139  if (!caught) abort();
140
141  caught = 0;
142  try { fnc((C *)e); }
143  catch(C *p) { caught = 1; if (p != e) abort();}
144  catch(...) { abort(); }
145  if (!caught) abort();
146
147  caught = 0;
148  try { fnc((C *)e); }
149  catch(B *p) { abort(); }
150  catch(D *p) { abort(); }
151  catch(...) { caught =1; }
152  if (!caught) abort();
153
154  // try with AA object
155  caught = 0;
156  try { fnaa((AA *)e); }
157  catch(A *p) { caught = 1; if (p != (AA *)e) abort();}
158  catch(...) { abort(); }
159  if (!caught) abort();
160
161  caught = 0;
162  try { fnaa((AA *)e); }
163  catch(AA *p) { caught = 1; if (p != e) abort();}
164  catch(...) { abort(); }
165  if (!caught) abort();
166
167  caught = 0;
168  try { fnaa((AA *)e); }
169  catch(C *p) { abort(); }
170  catch(B *p) { abort(); }
171  catch(D *p) { abort(); }
172  catch(...) { caught =1; }
173  if (!caught) abort();
174
175  return;
176}
177
178int main ()
179{
180  E e;
181  check (&e); // try with an object
182  check ((E *)0); // try with no object
183
184  return 0;
185}
186