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