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