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