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