1// { dg-do run  }
2// { dg-options "-w" }
3// Copyright (C) 1999, 2000 Free Software Foundation, Inc.
4// Contributed by Nathan Sidwell 6 Jun 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
12
13struct A { int m; };
14struct B : A { int m; };
15struct C : private A { int m; };
16struct D : B, C { int m; };
17
18void fna(A *obj) { throw obj; }
19void fnb(B *obj) { throw obj; }
20void fnc(C *obj) { throw obj; }
21void fnd(D *obj) { throw obj; }
22
23extern "C" void abort();
24
25void check(D *d)
26{
27  int caught;
28
29  // try with whole object
30  caught = 0;
31  try { fnd(d); }
32  catch(A *p) { abort(); } // A is ambiguous
33  catch(D *p) { caught = 1; if (p != d) abort();}
34  catch(...) { abort(); }
35  if (!caught) abort();
36
37  caught = 0;
38  try { fnd(d); }
39  catch(A *p) { abort(); } // A is ambiguous
40  catch(B *p) { caught = 1; if (p != d) abort();}
41  catch(...) { abort(); }
42  if (!caught) abort();
43
44  caught = 0;
45  try { fnd(d); }
46  catch(A *p) { abort(); } // A is ambiguous
47  catch(C *p) { caught = 1; if (p != d) abort();}
48  catch(...) { abort(); }
49  if (!caught) abort();
50
51  // try with an A object
52  caught = 0;
53  try { fna((B *)d); }
54  catch(B *p) { abort(); } // throw type is static type
55  catch(A *p) { caught = 1; if (p != (B *)d) abort();}
56  catch(...) { abort(); }
57  if (!caught) abort();
58
59  caught = 0;
60  try { fna((A *)(C *)d); }
61  catch(C *p) { abort(); } // throw type is static type
62  catch(A *p) { caught = 1; if (p != (A *)(C *)d) abort();}
63  catch(...) { abort(); }
64  if (!caught) abort();
65
66  // try with B object
67  caught = 0;
68  try { fnb((B *)d); }
69  catch(A *p) { caught = 1; if (p != (B *)d) abort();}
70  catch(...) { abort(); }
71  if (!caught) abort();
72
73  caught = 0;
74  try { fnb((B *)d); }
75  catch(B *p) { caught = 1; if (p != d) abort();}
76  catch(...) { abort(); }
77  if (!caught) abort();
78
79  caught = 0;
80  try { fnb((B *)d); }
81  catch(C *p) { abort(); }
82  catch(D *p) { abort(); }
83  catch(...) { caught =1; }
84  if (!caught) abort();
85
86  caught = 0;
87  try { fnc((C *)d); }
88  catch(A *p) { abort();}
89  catch(C *p) { caught = 1; if (p != d) abort();}
90  catch(...) { abort(); }
91  if (!caught) abort();
92
93  caught = 0;
94  try { fnc((C *)d); }
95  catch(B *p) { abort(); }
96  catch(D *p) { abort(); }
97  catch(...) { caught =1; }
98  if (!caught) abort();
99
100  return;
101}
102
103int main ()
104{
105  D d;
106  check (&d); // try with an object
107  check ((D *)0); // try with no object
108
109  return 0;
110}
111