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