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
14struct A { int m; virtual ~A(){}};
15struct B : A { int m; };
16struct C : A { int m; };
17struct D : B, C { int m; };
18
19void fna(A *obj) { throw obj; }
20void fnb(B *obj) { throw obj; }
21void fnc(C *obj) { throw obj; }
22void fnd(D *obj) { throw obj; }
23
24extern "C" void abort();
25
26void 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
110int 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