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