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