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 public
7 // DAG.
8 // -- public, << private, == virtual
9 
10 // D--B--A
11 // +--C--A
12 
13 #include <cstdio>
14 
15 struct A { int m; };
16 struct B : A { int m; };
17 struct C : A { int m; };
18 struct D : B, C { int m; };
19 
fna(A * obj)20 void fna(A *obj) { throw obj; }
fnb(B * obj)21 void fnb(B *obj) { throw obj; }
fnc(C * obj)22 void fnc(C *obj) { throw obj; }
fnd(D * obj)23 void fnd(D *obj) { throw obj; }
24 
25 extern "C" void abort();
26 
check(D * d)27 void check(D *d)
28 {
29   //fprintf(stderr, "D: %p\n", d);
30   //fprintf(stderr, "B: %p\n", (B*)d);
31   //fprintf(stderr, "A: %p\n", (A*)(B*)d);
32   //fprintf(stderr, "C: %p\n", (C*)d);
33   //fprintf(stderr, "A: %p\n", (A*)(C*)d);
34   int caught;
35 
36   // try with whole object
37   caught = 0;
38   try { fnd(d); }
39   catch(A *p) { abort(); } // A is ambiguous
40   catch(D *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(B *p) { caught = 1; if (p != d) abort();}
48   catch(...) { abort(); }
49   if (!caught) abort();
50 
51   caught = 0;
52   try { fnd(d); }
53   catch(A *p) { abort(); } // A is ambiguous
54   catch(C *p) { caught = 1; if (p != d) abort();}
55   catch(...) { abort(); }
56   if (!caught) abort();
57 
58   // try with an A object
59   caught = 0;
60   try { fna((B *)d); }
61   catch(B *p) { abort(); } // throw type is static type
62   catch(A *p) { caught = 1; if (p != (B *)d) abort();}
63   catch(...) { abort(); }
64   if (!caught) abort();
65 
66   caught = 0;
67   try { fna((C *)d); }
68   catch(C *p) { abort(); } // throw type is static type
69   catch(A *p) { caught = 1; if (p != (C *)d) abort();}
70   catch(...) { abort(); }
71   if (!caught) abort();
72 
73   // try with B object
74   caught = 0;
75   try { fnb((B *)d); }
76   catch(A *p) { caught = 1; if (p != (B *)d) abort();}
77   catch(...) { abort(); }
78   if (!caught) abort();
79 
80   caught = 0;
81   try { fnb((B *)d); }
82   catch(B *p) { caught = 1; if (p != (B *)d) abort();}
83   catch(...) { abort(); }
84   if (!caught) abort();
85 
86   caught = 0;
87   try { fnb((B *)d); }
88   catch(C *p) { abort(); }
89   catch(D *p) { abort(); }
90   catch(...) { caught =1; }
91   if (!caught) abort();
92 
93   // try with C object
94   caught = 0;
95   try { fnc((C *)d); }
96   catch(A *p) { caught = 1; if (p != (C *)d) abort();}
97   catch(...) { abort(); }
98   if (!caught) abort();
99 
100   caught = 0;
101   try { fnc((C *)d); }
102   catch(C *p) { caught = 1; if (p != d) abort();}
103   catch(...) { abort(); }
104   if (!caught) abort();
105 
106   caught = 0;
107   try { fnc((C *)d); }
108   catch(B *p) { abort(); }
109   catch(D *p) { abort(); }
110   catch(...) { caught =1; }
111   if (!caught) abort();
112 
113   return;
114 }
115 
main()116 int main ()
117 {
118   D d;
119   check (&d); // try with an object
120   check ((D *)0); // try with no object
121 
122   return 0;
123 }
124