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