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 ~AA13struct A { int m; virtual ~A(){}}; 14 struct B : virtual A { int m; }; 15 struct C : virtual 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) { 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 main()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