1// Copyright (C) 1999, 2000 Free Software Foundation, Inc.
2// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org>
3
4// We cannot catch an ambiguous base class. Check with a virtual
5// polymorphic public DAG.
6// -- public, << private, == virtual
7
8// D--B==A
9// +--C==A
10
11// Special g++ Options: -w
12
13struct A { int m; virtual ~A(){}};
14struct B : virtual A { int m; };
15struct C : virtual 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) { caught = 1; if (p != d) abort();}
33  catch(...) { abort(); }
34  if (!caught) abort();
35
36  caught = 0;
37  try { fnd(d); }
38  catch(B *p) { caught = 1; if (p != d) abort();}
39  catch(...) { abort(); }
40  if (!caught) abort();
41
42  caught = 0;
43  try { fnd(d); }
44  catch(C *p) { caught = 1; if (p != d) abort();}
45  catch(...) { abort(); }
46  if (!caught) abort();
47
48  // try with an A object
49  caught = 0;
50  try { fna((B *)d); }
51  catch(B *p) { abort(); } // throw type is static type
52  catch(A *p) { caught = 1; if (p != d) abort();}
53  catch(...) { abort(); }
54  if (!caught) abort();
55
56  caught = 0;
57  try { fna((C *)d); }
58  catch(C *p) { abort(); } // throw type is static type
59  catch(A *p) { caught = 1; if (p != d) abort();}
60  catch(...) { abort(); }
61  if (!caught) abort();
62
63  // try with B object
64  caught = 0;
65  try { fnb((B *)d); }
66  catch(A *p) { caught = 1; if (p != d) abort();}
67  catch(...) { abort(); }
68  if (!caught) abort();
69
70  caught = 0;
71  try { fnb((B *)d); }
72  catch(B *p) { caught = 1; if (p != d) abort();}
73  catch(...) { abort(); }
74  if (!caught) abort();
75
76  caught = 0;
77  try { fnb((B *)d); }
78  catch(C *p) { abort(); }
79  catch(D *p) { abort(); }
80  catch(...) { caught =1; }
81  if (!caught) abort();
82
83  // try with C object
84  caught = 0;
85  try { fnc((C *)d); }
86  catch(A *p) { caught = 1; if (p != d) abort();}
87  catch(...) { abort(); }
88  if (!caught) abort();
89
90  caught = 0;
91  try { fnc((C *)d); }
92  catch(C *p) { caught = 1; if (p != d) abort();}
93  catch(...) { abort(); }
94  if (!caught) abort();
95
96  caught = 0;
97  try { fnc((C *)d); }
98  catch(B *p) { abort(); }
99  catch(D *p) { abort(); }
100  catch(...) { caught =1; }
101  if (!caught) abort();
102
103  return;
104}
105
106int main ()
107{
108  D d;
109  check (&d); // try with an object
110  check ((D *)0); // try with no object
111
112  return 0;
113}
114