1*c87b03e5Sespie // Copyright (C) 1999, 2000 Free Software Foundation, Inc. 2*c87b03e5Sespie // Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> 3*c87b03e5Sespie 4*c87b03e5Sespie // We cannot catch an ambiguous base class. Check with a virtual 5*c87b03e5Sespie // polymorphic public DAG. 6*c87b03e5Sespie // -- public, << private, == virtual 7*c87b03e5Sespie 8*c87b03e5Sespie // D--B==A 9*c87b03e5Sespie // +--C==A 10*c87b03e5Sespie 11*c87b03e5Sespie // Special g++ Options: -w 12*c87b03e5Sespie ~AA13*c87b03e5Sespiestruct A { int m; virtual ~A(){}}; 14*c87b03e5Sespie struct B : virtual A { int m; }; 15*c87b03e5Sespie struct C : virtual A { int m; }; 16*c87b03e5Sespie struct D : B, C { int m; }; 17*c87b03e5Sespie fna(A * obj)18*c87b03e5Sespievoid fna(A *obj) { throw obj; } fnb(B * obj)19*c87b03e5Sespievoid fnb(B *obj) { throw obj; } fnc(C * obj)20*c87b03e5Sespievoid fnc(C *obj) { throw obj; } fnd(D * obj)21*c87b03e5Sespievoid fnd(D *obj) { throw obj; } 22*c87b03e5Sespie 23*c87b03e5Sespie extern "C" void abort(); 24*c87b03e5Sespie check(D * d)25*c87b03e5Sespievoid check(D *d) 26*c87b03e5Sespie { 27*c87b03e5Sespie int caught; 28*c87b03e5Sespie 29*c87b03e5Sespie // try with whole object 30*c87b03e5Sespie caught = 0; 31*c87b03e5Sespie try { fnd(d); } 32*c87b03e5Sespie catch(A *p) { caught = 1; if (p != d) abort();} 33*c87b03e5Sespie catch(...) { abort(); } 34*c87b03e5Sespie if (!caught) abort(); 35*c87b03e5Sespie 36*c87b03e5Sespie caught = 0; 37*c87b03e5Sespie try { fnd(d); } 38*c87b03e5Sespie catch(B *p) { caught = 1; if (p != d) abort();} 39*c87b03e5Sespie catch(...) { abort(); } 40*c87b03e5Sespie if (!caught) abort(); 41*c87b03e5Sespie 42*c87b03e5Sespie caught = 0; 43*c87b03e5Sespie try { fnd(d); } 44*c87b03e5Sespie catch(C *p) { caught = 1; if (p != d) abort();} 45*c87b03e5Sespie catch(...) { abort(); } 46*c87b03e5Sespie if (!caught) abort(); 47*c87b03e5Sespie 48*c87b03e5Sespie // try with an A object 49*c87b03e5Sespie caught = 0; 50*c87b03e5Sespie try { fna((B *)d); } 51*c87b03e5Sespie catch(B *p) { abort(); } // throw type is static type 52*c87b03e5Sespie catch(A *p) { caught = 1; if (p != d) abort();} 53*c87b03e5Sespie catch(...) { abort(); } 54*c87b03e5Sespie if (!caught) abort(); 55*c87b03e5Sespie 56*c87b03e5Sespie caught = 0; 57*c87b03e5Sespie try { fna((C *)d); } 58*c87b03e5Sespie catch(C *p) { abort(); } // throw type is static type 59*c87b03e5Sespie catch(A *p) { caught = 1; if (p != d) abort();} 60*c87b03e5Sespie catch(...) { abort(); } 61*c87b03e5Sespie if (!caught) abort(); 62*c87b03e5Sespie 63*c87b03e5Sespie // try with B object 64*c87b03e5Sespie caught = 0; 65*c87b03e5Sespie try { fnb((B *)d); } 66*c87b03e5Sespie catch(A *p) { caught = 1; if (p != d) abort();} 67*c87b03e5Sespie catch(...) { abort(); } 68*c87b03e5Sespie if (!caught) abort(); 69*c87b03e5Sespie 70*c87b03e5Sespie caught = 0; 71*c87b03e5Sespie try { fnb((B *)d); } 72*c87b03e5Sespie catch(B *p) { caught = 1; if (p != d) abort();} 73*c87b03e5Sespie catch(...) { abort(); } 74*c87b03e5Sespie if (!caught) abort(); 75*c87b03e5Sespie 76*c87b03e5Sespie caught = 0; 77*c87b03e5Sespie try { fnb((B *)d); } 78*c87b03e5Sespie catch(C *p) { abort(); } 79*c87b03e5Sespie catch(D *p) { abort(); } 80*c87b03e5Sespie catch(...) { caught =1; } 81*c87b03e5Sespie if (!caught) abort(); 82*c87b03e5Sespie 83*c87b03e5Sespie // try with C object 84*c87b03e5Sespie caught = 0; 85*c87b03e5Sespie try { fnc((C *)d); } 86*c87b03e5Sespie catch(A *p) { caught = 1; if (p != d) abort();} 87*c87b03e5Sespie catch(...) { abort(); } 88*c87b03e5Sespie if (!caught) abort(); 89*c87b03e5Sespie 90*c87b03e5Sespie caught = 0; 91*c87b03e5Sespie try { fnc((C *)d); } 92*c87b03e5Sespie catch(C *p) { caught = 1; if (p != d) abort();} 93*c87b03e5Sespie catch(...) { abort(); } 94*c87b03e5Sespie if (!caught) abort(); 95*c87b03e5Sespie 96*c87b03e5Sespie caught = 0; 97*c87b03e5Sespie try { fnc((C *)d); } 98*c87b03e5Sespie catch(B *p) { abort(); } 99*c87b03e5Sespie catch(D *p) { abort(); } 100*c87b03e5Sespie catch(...) { caught =1; } 101*c87b03e5Sespie if (!caught) abort(); 102*c87b03e5Sespie 103*c87b03e5Sespie return; 104*c87b03e5Sespie } 105*c87b03e5Sespie main()106*c87b03e5Sespieint main () 107*c87b03e5Sespie { 108*c87b03e5Sespie D d; 109*c87b03e5Sespie check (&d); // try with an object 110*c87b03e5Sespie check ((D *)0); // try with no object 111*c87b03e5Sespie 112*c87b03e5Sespie return 0; 113*c87b03e5Sespie } 114