1246149Ssjg// { dg-do run  }
2246149Ssjg// { dg-options "-w" }
3246149Ssjg// Copyright (C) 1999, 2000 Free Software Foundation, Inc.
4246149Ssjg// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org>
5246149Ssjg
6246149Ssjg// We cannot catch an ambiguous base class.
7246149Ssjg// -- public, << private, == virtual
8246149Ssjg
9246149Ssjg// different levels
10246149Ssjg// F--D--B--A
11246149Ssjg//    +--C--A
12246149Ssjg// +--E--A
13246149Ssjg
14246149Ssjg
15246149Ssjgstruct A { int m; virtual ~A(){}};
16246149Ssjgstruct B : A { int m; };
17246149Ssjgstruct C : A { int m; };
18246149Ssjgstruct D : B, C { int m; };
19246149Ssjgstruct E : A { int m; };
20246149Ssjgstruct F : D, E { int m; };
21246149Ssjg
22246149Ssjgvoid fna(A *obj) { throw obj; }
23246149Ssjgvoid fnb(B *obj) { throw obj; }
24246149Ssjgvoid fnc(C *obj) { throw obj; }
25246149Ssjgvoid fnd(D *obj) { throw obj; }
26246149Ssjgvoid fne(E *obj) { throw obj; }
27246149Ssjgvoid fnf(F *obj) { throw obj; }
28246149Ssjg
29246149Ssjgextern "C" void abort();
30246149Ssjg
31246149Ssjgvoid check(F *f)
32246149Ssjg{
33246149Ssjg  int caught;
34246149Ssjg
35246149Ssjg  // try with whole object
36246149Ssjg  caught = 0;
37246149Ssjg  try { fnf(f); }
38250837Ssjg  catch(A *p) { abort(); } // A is ambiguous
39246149Ssjg  catch(F *p) { caught = 1; if (p != f) abort();}
40249033Ssjg  catch(...) { abort(); }
41249033Ssjg  if (!caught) abort();
42246149Ssjg
43246149Ssjg  caught = 0;
44246149Ssjg  try { fnf(f); }
45246149Ssjg  catch(A *p) { abort(); } // A is ambiguous
46246149Ssjg  catch(E *p) { caught = 1; if (p != f) abort();}
47246149Ssjg  catch(...) { abort(); }
48246149Ssjg  if (!caught) abort();
49246149Ssjg
50246149Ssjg  caught = 0;
51246149Ssjg  try { fnf(f); }
52246149Ssjg  catch(A *p) { abort(); } // A is ambiguous
53246149Ssjg  catch(D *p) { caught = 1; if (p != f) abort();}
54246149Ssjg  catch(...) { abort(); }
55246149Ssjg  if (!caught) abort();
56246149Ssjg
57246149Ssjg  caught = 0;
58246149Ssjg  try { fnf(f); }
59246149Ssjg  catch(A *p) { abort(); } // A is ambiguous
60246149Ssjg  catch(B *p) { caught = 1; if (p != f) abort();}
61246149Ssjg  catch(...) { abort(); }
62246149Ssjg  if (!caught) abort();
63246149Ssjg
64246149Ssjg  caught = 0;
65246149Ssjg  try { fnf(f); }
66246149Ssjg  catch(A *p) { abort(); } // A is ambiguous
67246149Ssjg  catch(C *p) { caught = 1; if (p != f) abort();}
68246149Ssjg  catch(...) { abort(); }
69246149Ssjg  if (!caught) abort();
70246149Ssjg
71246149Ssjg  // try with D object
72246149Ssjg  caught = 0;
73246149Ssjg  try { fnd(f); }
74246149Ssjg  catch(A *p) { abort(); } // A is ambiguous
75246149Ssjg  catch(D *p) { caught = 1; if (p != f) abort();}
76246149Ssjg  catch(...) { abort(); }
77246149Ssjg  if (!caught) abort();
78246149Ssjg
79246149Ssjg  caught = 0;
80246149Ssjg  try { fnd(f); }
81246149Ssjg  catch(A *p) { abort(); } // A is ambiguous
82246149Ssjg  catch(B *p) { caught = 1; if (p != f) abort();}
83246149Ssjg  catch(...) { abort(); }
84246149Ssjg  if (!caught) abort();
85246149Ssjg
86246149Ssjg  caught = 0;
87246149Ssjg  try { fnd(f); }
88246149Ssjg  catch(A *p) { abort(); } // A is ambiguous
89246149Ssjg  catch(C *p) { caught = 1; if (p != f) abort();}
90246149Ssjg  catch(...) { abort(); }
91246149Ssjg  if (!caught) abort();
92246149Ssjg
93246149Ssjg  // try with E object
94246149Ssjg  caught = 0;
95246149Ssjg  try { fne(f); }
96246149Ssjg  catch(A *p) { caught = 1; if (p != (E *)f) abort();}
97246149Ssjg  catch(...) { abort(); }
98246149Ssjg  if (!caught) abort();
99246149Ssjg
100246149Ssjg  caught = 0;
101246149Ssjg  try { fne(f); }
102246149Ssjg  catch(E *p) { caught = 1; if (p != f) abort();}
103246149Ssjg  catch(...) { abort(); }
104246149Ssjg  if (!caught) abort();
105246149Ssjg
106246149Ssjg  caught = 0;
107246149Ssjg  try { fne(f); }
108246149Ssjg  catch(F *p) { abort(); }
109246149Ssjg  catch(...) { caught = 1; }
110246149Ssjg  if (!caught) abort();
111246149Ssjg
112246149Ssjg  // try with an A object
113246149Ssjg  caught = 0;
114246149Ssjg  try { fna((B *)f); }
115246149Ssjg  catch(B *p) { abort(); } // throw type is static type
116246149Ssjg  catch(A *p) { caught = 1; if (p != (B *)f) abort();}
117246149Ssjg  catch(...) { abort(); }
118246149Ssjg  if (!caught) abort();
119246149Ssjg
120246149Ssjg  caught = 0;
121246149Ssjg  try { fna((C *)f); }
122246149Ssjg  catch(C *p) { abort(); } // throw type is static type
123246149Ssjg  catch(A *p) { caught = 1; if (p != (C *)f) abort();}
124246149Ssjg  catch(...) { abort(); }
125246149Ssjg  if (!caught) abort();
126246149Ssjg
127250837Ssjg  caught = 0;
128250837Ssjg  try { fna((E *)f); }
129250837Ssjg  catch(E *p) { abort(); } // throw type is static type
130250837Ssjg  catch(A *p) { caught = 1; if (p != (E *)f) abort();}
131250837Ssjg  catch(...) { abort(); }
132250837Ssjg  if (!caught) abort();
133246149Ssjg
134246149Ssjg  // try with B object
135246149Ssjg  caught = 0;
136246149Ssjg  try { fnb((B *)f); }
137246149Ssjg  catch(A *p) { caught = 1; if (p != (B *)f) abort();}
138246149Ssjg  catch(...) { abort(); }
139246149Ssjg  if (!caught) abort();
140246149Ssjg
141246149Ssjg  caught = 0;
142246149Ssjg  try { fnb((B *)f); }
143246149Ssjg  catch(B *p) { caught = 1; if (p != f) abort();}
144246149Ssjg  catch(...) { abort(); }
145246149Ssjg  if (!caught) abort();
146246149Ssjg
147246149Ssjg  caught = 0;
148246149Ssjg  try { fnb((B *)f); }
149246149Ssjg  catch(C *p) { abort(); }
150246149Ssjg  catch(D *p) { abort(); }
151246149Ssjg  catch(...) { caught =1; }
152246149Ssjg  if (!caught) abort();
153246149Ssjg
154246149Ssjg  // try with C object
155246149Ssjg  caught = 0;
156246149Ssjg  try { fnc((C *)f); }
157246149Ssjg  catch(A *p) { caught = 1; if (p != (C *)f) abort();}
158246149Ssjg  catch(...) { abort(); }
159249033Ssjg  if (!caught) abort();
160246149Ssjg
161250837Ssjg  caught = 0;
162250837Ssjg  try { fnc((C *)f); }
163250837Ssjg  catch(C *p) { caught = 1; if (p != f) abort();}
164246149Ssjg  catch(...) { abort(); }
165246149Ssjg  if (!caught) abort();
166246149Ssjg
167246149Ssjg  caught = 0;
168246149Ssjg  try { fnc((C *)f); }
169246149Ssjg  catch(B *p) { abort(); }
170246149Ssjg  catch(D *p) { abort(); }
171246149Ssjg  catch(...) { caught =1; }
172246149Ssjg  if (!caught) abort();
173246149Ssjg
174246149Ssjg  return;
175246149Ssjg}
176246149Ssjg
177246149Ssjgint main ()
178246149Ssjg{
179246149Ssjg  F f;
180246149Ssjg  check (&f); // try with an object
181246149Ssjg  check ((F *)0); // try with no object
182246149Ssjg
183246149Ssjg  return 0;
184246149Ssjg}
185246149Ssjg