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 (at) acm.org> 5 6 // We cannot catch an ambiguous base class. 7 // -- public, << private, == virtual 8 9 // different levels 10 // F--D--B--A 11 // +--C--A 12 // +--E--A 13 14 #include <stdio.h> 15 16 struct A { int m; }; 17 struct B : A { int m; }; 18 struct C : A { int m; }; 19 struct D : B, C { int m; }; 20 struct E : A { int m; }; 21 struct F : D, E { int m; }; 22 23 void fna(A *obj) { 24 throw obj; 25 } 26 void fnb(B *obj) { 27 throw obj; 28 } 29 void fnc(C *obj) { 30 throw obj; 31 } 32 void fnd(D *obj) { 33 throw obj; 34 } 35 void fne(E *obj) { 36 throw obj; 37 } 38 void fnf(F *obj) { 39 throw obj; 40 } 41 42 extern "C" void abort(); 43 44 void check(F *f) 45 { 46 int caught; 47 48 // try with whole object 49 caught = 0; 50 try { fnf(f); } 51 catch(A *p) { abort(); } // A is ambiguous 52 catch(F *p) { caught = 1; if (p != f) abort();} 53 catch(...) { abort(); } 54 if (!caught) abort(); 55 56 caught = 0; 57 try { fnf(f); } 58 catch(A *p) { abort(); } // A is ambiguous 59 catch(E *p) { caught = 1; if (p != f) abort();} 60 catch(...) { abort(); } 61 if (!caught) abort(); 62 63 caught = 0; 64 try { fnf(f); } 65 catch(A *p) { abort(); } // A is ambiguous 66 catch(D *p) { caught = 1; if (p != f) abort();} 67 catch(...) { abort(); } 68 if (!caught) abort(); 69 70 caught = 0; 71 try { fnf(f); } 72 catch(A *p) { abort(); } // A is ambiguous 73 catch(B *p) { caught = 1; if (p != f) abort();} 74 catch(...) { abort(); } 75 if (!caught) abort(); 76 77 caught = 0; 78 try { fnf(f); } 79 catch(A *p) { abort(); } // A is ambiguous 80 catch(C *p) { caught = 1; if (p != f) abort();} 81 catch(...) { abort(); } 82 if (!caught) abort(); 83 84 // try with D object 85 caught = 0; 86 try { fnd(f); } 87 catch(A *p) { abort(); } // A is ambiguous 88 catch(D *p) { caught = 1; if (p != f) abort();} 89 catch(...) { abort(); } 90 if (!caught) abort(); 91 92 caught = 0; 93 try { fnd(f); } 94 catch(A *p) { abort(); } // A is ambiguous 95 catch(B *p) { caught = 1; if (p != f) abort();} 96 catch(...) { abort(); } 97 if (!caught) abort(); 98 99 caught = 0; 100 try { fnd(f); } 101 catch(A *p) { abort(); } // A is ambiguous 102 catch(C *p) { caught = 1; if (p != f) abort();} 103 catch(...) { abort(); } 104 if (!caught) abort(); 105 106 // try with E object 107 caught = 0; 108 try { fne(f); } 109 catch(A *p) { caught = 1; if (p != (E *)f) abort();} 110 catch(...) { abort(); } 111 if (!caught) abort(); 112 113 caught = 0; 114 try { fne(f); } 115 catch(E *p) { caught = 1; if (p != f) abort();} 116 catch(...) { abort(); } 117 if (!caught) abort(); 118 119 caught = 0; 120 try { fne(f); } 121 catch(F *p) { abort(); } 122 catch(...) { caught = 1; } 123 if (!caught) abort(); 124 125 // try with an A object 126 caught = 0; 127 try { fna((B *)f); } 128 catch(B *p) { abort(); } // throw type is static type 129 catch(A *p) { caught = 1; if (p != (B *)f) abort();} 130 catch(...) { abort(); } 131 if (!caught) abort(); 132 133 caught = 0; 134 try { fna((C *)f); } 135 catch(C *p) { abort(); } // throw type is static type 136 catch(A *p) { caught = 1; if (p != (C *)f) abort();} 137 catch(...) { abort(); } 138 if (!caught) abort(); 139 140 caught = 0; 141 try { fna((E *)f); } 142 catch(E *p) { abort(); } // throw type is static type 143 catch(A *p) { caught = 1; if (p != (E *)f) abort();} 144 catch(...) { abort(); } 145 if (!caught) abort(); 146 147 // try with B object 148 caught = 0; 149 try { fnb((B *)f); } 150 catch(A *p) { caught = 1; if (p != (B *)f) abort();} 151 catch(...) { abort(); } 152 if (!caught) abort(); 153 154 caught = 0; 155 try { fnb((B *)f); } 156 catch(B *p) { caught = 1; if (p != f) abort();} 157 catch(...) { abort(); } 158 if (!caught) abort(); 159 160 caught = 0; 161 try { fnb((B *)f); } 162 catch(C *p) { abort(); } 163 catch(D *p) { abort(); } 164 catch(...) { caught =1; } 165 if (!caught) abort(); 166 167 // try with C object 168 caught = 0; 169 try { fnc((C *)f); } 170 catch(A *p) { caught = 1; if (p != (C *)f) abort();} 171 catch(...) { abort(); } 172 if (!caught) abort(); 173 174 caught = 0; 175 try { fnc((C *)f); } 176 catch(C *p) { caught = 1; if (p != f) abort();} 177 catch(...) { abort(); } 178 if (!caught) abort(); 179 180 caught = 0; 181 try { fnc((C *)f); } 182 catch(B *p) { abort(); } 183 catch(D *p) { abort(); } 184 catch(...) { caught =1; } 185 if (!caught) abort(); 186 187 return; 188 } 189 190 int main () 191 { 192 F f; 193 check (&f); // try with an object 194 check ((F *)0); // try with no object 195 196 return 0; 197 } 198