diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b2255e837ef4110e20bacd8af78072ce8a430901..65639f39ea8e7a96530944f537c093384bdb681c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,25 @@ +Tue Sep 21 15:38:10 BST 1999 Nathan Sidwell <nathan@acm.org> + + * g++.old-deja/g++.other/dyncast1.C: New test. + * g++.old-deja/g++.other/dyncast2.C: New test. + * g++.old-deja/g++.other/dyncast3.C: New test. + * g++.old-deja/g++.other/dyncast4.C: New test. + * g++.old-deja/g++.other/dyncast5.C: New test. + * g++.old-deja/g++.eh/catch3.C: New test. + * g++.old-deja/g++.eh/catch3p.C: New test. + * g++.old-deja/g++.eh/catch4.C: New test. + * g++.old-deja/g++.eh/catch4p.C: New test. + * g++.old-deja/g++.eh/catch5.C: New test. + * g++.old-deja/g++.eh/catch5p.C: New test. + * g++.old-deja/g++.eh/catch6.C: New test. + * g++.old-deja/g++.eh/catch6p.C: New test. + * g++.old-deja/g++.eh/catch7.C: New test. + * g++.old-deja/g++.eh/catch7p.C: New test. + * g++.old-deja/g++.eh/catch8.C: New test. + * g++.old-deja/g++.eh/catch8p.C: New test. + * g++.old-deja/g++.eh/catch9.C: New test. + * g++.old-deja/g++.eh/catch9p.C: New test. + Mon Sep 13 14:14:21 BST 1999 Nathan Sidwell <nathan@acm.org> * g++.old-deja/g++.other/sizeof3.C: Remove XFAILS. diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch3.C b/gcc/testsuite/g++.old-deja/g++.eh/catch3.C new file mode 100644 index 0000000000000000000000000000000000000000..0451d77ca7f37923ff2d3481fb946d143bfb538f --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch3.C @@ -0,0 +1,114 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. Check with a non-virtual public +// DAG. +// -- public, << private, == virtual + +// D--B--A +// +--C--A + +struct A { int m; }; +struct B : A { int m; }; +struct C : A { int m; }; +struct D : B, C { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch3p.C b/gcc/testsuite/g++.old-deja/g++.eh/catch3p.C new file mode 100644 index 0000000000000000000000000000000000000000..33873aa3cbe99443926cf957d93e2be9e191139d --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch3p.C @@ -0,0 +1,114 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. Check with a non-virtual +// polymorphic public DAG. +// -- public, << private, == virtual + +// D--B--A +// +--C--A + +struct A { int m; virtual ~A(){}}; +struct B : A { int m; }; +struct C : A { int m; }; +struct D : B, C { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch4.C b/gcc/testsuite/g++.old-deja/g++.eh/catch4.C new file mode 100644 index 0000000000000000000000000000000000000000..94c602c7e0a8ebb361a01cc2134fbb430cc74f42 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch4.C @@ -0,0 +1,111 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. Check with a virtual public +// DAG. +// -- public, << private, == virtual + +// D--B==A +// +--C==A + +struct A { int m; }; +struct B : virtual A { int m; }; +struct C : virtual A { int m; }; +struct D : B, C { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch4p.C b/gcc/testsuite/g++.old-deja/g++.eh/catch4p.C new file mode 100644 index 0000000000000000000000000000000000000000..19c2273ec564ca88b1ce8c73264f134cc187905c --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch4p.C @@ -0,0 +1,111 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. Check with a virtual +// polymorphic public DAG. +// -- public, << private, == virtual + +// D--B==A +// +--C==A + +struct A { int m; virtual ~A(){}}; +struct B : virtual A { int m; }; +struct C : virtual A { int m; }; +struct D : B, C { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch5.C b/gcc/testsuite/g++.old-deja/g++.eh/catch5.C new file mode 100644 index 0000000000000000000000000000000000000000..9dff637ade18e1310e5a59c154d5d70c28c1ccb7 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch5.C @@ -0,0 +1,151 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// D--B==A +// +--C==A +// +--AA-A + +struct A { int m; }; +struct B : virtual A { int m; }; +struct C : virtual A { int m; }; +struct AA : A { int m; }; +struct D : B, C, AA { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } +void fnaa(AA *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(AA *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((AA *)d); } + catch(AA *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (AA *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with AA object + caught = 0; + try { fnaa((AA *)d); } + catch(A *p) { caught = 1; if (p != (AA *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnaa((AA *)d); } + catch(AA *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnaa((AA *)d); } + catch(C *p) { abort(); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch5p.C b/gcc/testsuite/g++.old-deja/g++.eh/catch5p.C new file mode 100644 index 0000000000000000000000000000000000000000..c6a5d0a0b1ff9087acf5f6ebccf782398159ddd8 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch5p.C @@ -0,0 +1,151 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// D--B==A +// +--C==A +// +--AA-A + +struct A { int m; virtual ~A(){}}; +struct B : virtual A { int m; }; +struct C : virtual A { int m; }; +struct AA : A { int m; }; +struct D : B, C, AA { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } +void fnaa(AA *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(AA *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((AA *)d); } + catch(AA *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (AA *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with AA object + caught = 0; + try { fnaa((AA *)d); } + catch(A *p) { caught = 1; if (p != (AA *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnaa((AA *)d); } + catch(AA *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnaa((AA *)d); } + catch(C *p) { abort(); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch6.C b/gcc/testsuite/g++.old-deja/g++.eh/catch6.C new file mode 100644 index 0000000000000000000000000000000000000000..1ac48124c9846fb69880a04879b1ff82d476e84f --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch6.C @@ -0,0 +1,182 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// E==D--B==A +// +--C==A +// +--AA-A + +struct A { int m; }; +struct B : virtual A { int m; }; +struct C : virtual A { int m; }; +struct AA : A { int m; }; +struct D : B, C, AA { int m; }; +struct E : virtual D { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } +void fnaa(AA *obj) { throw obj; } +void fne(E *obj) { throw obj; } + +extern "C" void abort(); + +void check(E *e) +{ + int caught; + + // try with whole object + caught = 0; + try { fne(e); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(e); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(e); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(e); } + catch(A *p) { abort(); } // A is ambiguous + catch(AA *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with D oject + caught = 0; + try { fnd((D *)e); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd((D *)e); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd((D *)e); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd((D *)e); } + catch(A *p) { abort(); } // A is ambiguous + catch(AA *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)e); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)e); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((AA *)e); } + catch(AA *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (AA *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)e); } + catch(A *p) { caught = 1; if (p != (B *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)e); } + catch(B *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)e); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)e); } + catch(A *p) { caught = 1; if (p != (C *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)e); } + catch(C *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)e); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with AA object + caught = 0; + try { fnaa((AA *)e); } + catch(A *p) { caught = 1; if (p != (AA *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnaa((AA *)e); } + catch(AA *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnaa((AA *)e); } + catch(C *p) { abort(); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + E e; + check (&e); // try with an object + check ((E *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch6p.C b/gcc/testsuite/g++.old-deja/g++.eh/catch6p.C new file mode 100644 index 0000000000000000000000000000000000000000..3aac1a789cc715100f2ed88228b292777cebd0c5 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch6p.C @@ -0,0 +1,182 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// E==D--B==A +// +--C==A +// +--AA-A + +struct A { int m; virtual ~A(){}}; +struct B : virtual A { int m; }; +struct C : virtual A { int m; }; +struct AA : A { int m; }; +struct D : B, C, AA { int m; }; +struct E : virtual D { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } +void fnaa(AA *obj) { throw obj; } +void fne(E *obj) { throw obj; } + +extern "C" void abort(); + +void check(E *e) +{ + int caught; + + // try with whole object + caught = 0; + try { fne(e); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(e); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(e); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(e); } + catch(A *p) { abort(); } // A is ambiguous + catch(AA *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with D oject + caught = 0; + try { fnd((D *)e); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd((D *)e); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd((D *)e); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd((D *)e); } + catch(A *p) { abort(); } // A is ambiguous + catch(AA *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)e); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)e); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((AA *)e); } + catch(AA *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (AA *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)e); } + catch(A *p) { caught = 1; if (p != (B *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)e); } + catch(B *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)e); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)e); } + catch(A *p) { caught = 1; if (p != (C *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)e); } + catch(C *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)e); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with AA object + caught = 0; + try { fnaa((AA *)e); } + catch(A *p) { caught = 1; if (p != (AA *)e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnaa((AA *)e); } + catch(AA *p) { caught = 1; if (p != e) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnaa((AA *)e); } + catch(C *p) { abort(); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + E e; + check (&e); // try with an object + check ((E *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch7.C b/gcc/testsuite/g++.old-deja/g++.eh/catch7.C new file mode 100644 index 0000000000000000000000000000000000000000..bf90e0e590b9e1dc8fd241e411841fc9f3ff0f37 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch7.C @@ -0,0 +1,181 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// different levels +// F--D--B--A +// +--C--A +// +--E--A + +struct A { int m; }; +struct B : A { int m; }; +struct C : A { int m; }; +struct D : B, C { int m; }; +struct E : A { int m; }; +struct F : D, E { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } +void fne(E *obj) { throw obj; } +void fnf(F *obj) { throw obj; } + +extern "C" void abort(); + +void check(F *f) +{ + int caught; + + // try with whole object + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(F *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(E *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with D object + caught = 0; + try { fnd(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with E object + caught = 0; + try { fne(f); } + catch(A *p) { caught = 1; if (p != (E *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(f); } + catch(E *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(f); } + catch(F *p) { abort(); } + catch(...) { caught = 1; } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)f); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)f); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((E *)f); } + catch(E *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (E *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)f); } + catch(A *p) { caught = 1; if (p != (B *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)f); } + catch(B *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)f); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)f); } + catch(A *p) { caught = 1; if (p != (C *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)f); } + catch(C *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)f); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + F f; + check (&f); // try with an object + check ((F *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch7p.C b/gcc/testsuite/g++.old-deja/g++.eh/catch7p.C new file mode 100644 index 0000000000000000000000000000000000000000..be017c1a10be25490c7e41dc6276afa5f42e4812 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch7p.C @@ -0,0 +1,181 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// different levels +// F--D--B--A +// +--C--A +// +--E--A + +struct A { int m; virtual ~A(){}}; +struct B : A { int m; }; +struct C : A { int m; }; +struct D : B, C { int m; }; +struct E : A { int m; }; +struct F : D, E { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } +void fne(E *obj) { throw obj; } +void fnf(F *obj) { throw obj; } + +extern "C" void abort(); + +void check(F *f) +{ + int caught; + + // try with whole object + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(F *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(E *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnf(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with D object + caught = 0; + try { fnd(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(f); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with E object + caught = 0; + try { fne(f); } + catch(A *p) { caught = 1; if (p != (E *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(f); } + catch(E *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fne(f); } + catch(F *p) { abort(); } + catch(...) { caught = 1; } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)f); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)f); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((E *)f); } + catch(E *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (E *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)f); } + catch(A *p) { caught = 1; if (p != (B *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)f); } + catch(B *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)f); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)f); } + catch(A *p) { caught = 1; if (p != (C *)f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)f); } + catch(C *p) { caught = 1; if (p != f) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)f); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + F f; + check (&f); // try with an object + check ((F *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch8.C b/gcc/testsuite/g++.old-deja/g++.eh/catch8.C new file mode 100644 index 0000000000000000000000000000000000000000..685a4ec7d7fadaed849b9b9cd15873604c4bc85a --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch8.C @@ -0,0 +1,107 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 6 Jun 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// D--B--A +// +--C<<A + +struct A { int m; }; +struct B : A { int m; }; +struct C : private A { int m; }; +struct D : B, C { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((A *)(C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (A *)(C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(A *p) { abort();} + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch8p.C b/gcc/testsuite/g++.old-deja/g++.eh/catch8p.C new file mode 100644 index 0000000000000000000000000000000000000000..972761d17e5be16492788f7f2994f06366e06644 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch8p.C @@ -0,0 +1,108 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 6 Jun 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// D--B--A +// +--C<<A + +struct A { int m; virtual ~A(){}}; +struct B : A { int m; }; +struct C : private A { int m; }; +struct D : B, C { int m; }; + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((A *)(C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (A *)(C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { abort();} + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch9.C b/gcc/testsuite/g++.old-deja/g++.eh/catch9.C new file mode 100644 index 0000000000000000000000000000000000000000..13d8960e7160a93e27c9ce2980e458a094628f4e --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch9.C @@ -0,0 +1,114 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// D==B--A +// +==C--A + +struct A { int m; }; +struct B : A { int m; }; +struct C : A { int m; }; +struct D : virtual B, virtual C { int m; }; + + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(C *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catch9p.C b/gcc/testsuite/g++.old-deja/g++.eh/catch9p.C new file mode 100644 index 0000000000000000000000000000000000000000..ff7bf302d8477b8bb4d95a84bb4ccd8878cb4cf8 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/catch9p.C @@ -0,0 +1,114 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Aug 1999 <nathan@acm.org> + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// D==B--A +// +==C--A + +struct A { int m; virtual ~A(){}}; +struct B : A { int m; }; +struct C : A { int m; }; +struct D : virtual B, virtual C { int m; }; + + +void fna(A *obj) { throw obj; } +void fnb(B *obj) { throw obj; } +void fnc(C *obj) { throw obj; } +void fnd(D *obj) { throw obj; } + +extern "C" void abort(); + +void check(D *d) +{ + int caught; + + // try with whole object + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(D *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnd(d); } + catch(A *p) { abort(); } // A is ambiguous + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with an A object + caught = 0; + try { fna((B *)d); } + catch(B *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fna((C *)d); } + catch(C *p) { abort(); } // throw type is static type + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + // try with B object + caught = 0; + try { fnb((B *)d); } + catch(A *p) { caught = 1; if (p != (B *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(B *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnb((B *)d); } + catch(C *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + // try with C object + caught = 0; + try { fnc((C *)d); } + catch(A *p) { caught = 1; if (p != (C *)d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(C *p) { caught = 1; if (p != d) abort();} + catch(...) { abort(); } + if (!caught) abort(); + + caught = 0; + try { fnc((C *)d); } + catch(B *p) { abort(); } + catch(D *p) { abort(); } + catch(...) { caught =1; } + if (!caught) abort(); + + return; +} + +int main () +{ + D d; + check (&d); // try with an object + check ((D *)0); // try with no object + + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/dyncast1.C b/gcc/testsuite/g++.old-deja/g++.other/dyncast1.C new file mode 100644 index 0000000000000000000000000000000000000000..0a3a09b9a12f9699ff8f3e68fa7f535373e9f1d0 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast1.C @@ -0,0 +1,122 @@ +// Author: Alfred Miniarik <a8601248@unet.univie.ac.at> +// test of dynamic_cast +// runtime detecting of nonpublic +// inheritance within a cast +// and therefor failing with result 0. + +extern "C" void abort(); +extern "C" void printf(const char*, ...); + +static int errors = 0; +void error(int i) +{ + printf("Error %i\n",i); + errors++; +} + +// 1. downcast + +// 1.1. single inheritance case + +struct A {virtual ~A(){}}; +struct AA : A {}; +struct B : A {}; +struct BB : B {}; +class C : B {}; +struct D : C {}; + +struct CC : B {}; +class DD : CC {}; + +class CCC : protected B {}; +class DDD : protected CCC {}; + +void +test01 () +{ + D d; + if(dynamic_cast<D*> ((A*)&d)) error(1); + if(dynamic_cast<D*> ((B*)&d)) error(2); + if(&d != dynamic_cast<D*> ((C*)&d)) error(3); //counter example + if(dynamic_cast<C*> ((B*)&d)) error(4); + + DD dd; + if(dynamic_cast<DD*> ((A*)&dd)) error(5); + if(dynamic_cast<DD*> ((B*)&dd)) error(6); + + DDD ddd; + if(dynamic_cast<DDD*> ((A*)&ddd)) error(7); + if(dynamic_cast<DDD*> ((B*)&ddd)) error(8); + if(dynamic_cast<CCC*> ((B*)&ddd)) error(9); +} + +// 1.2. multiple inheritance case +// 1.2.1. all bases are public + +struct E : D, CC {}; +struct EE : CC, D {}; //Will search in reverse order. + +void +test02 () +{ + E e; + if(dynamic_cast<E*> ((A*)(D*)&e)) error(10); + if(dynamic_cast<E*> ((B*)(D*)&e)) error(11); + if(&e != dynamic_cast<E*> ((C*)(D*)&e)) error(12); //counter example + if(&e != dynamic_cast<E*> ((B*)(CC*)&e)) error(13); //counter example + if((CC*)&e != dynamic_cast<CC*> ((B*)(CC*)&e)) error(14); //counter example + + EE ee; + if(dynamic_cast<EE*> ((A*)(D*)&ee)) error(15); + if(dynamic_cast<EE*> ((B*)(D*)&ee)) error(16); + if(&ee != dynamic_cast<EE*> ((C*)(D*)&ee)) error(17); //counter example + if(&ee != dynamic_cast<EE*> ((B*)(CC*)&ee)) error(18); //counter example + if((CC*)&ee != dynamic_cast<CC*> ((B*)(CC*)&ee)) error(19); //counter example +} + +// 1.2.2 one or more branches are nonpublic + +struct X : private BB, E {}; +struct Y : AA, private B {}; + +class XX : BB, E {}; + +void +test03 () +{ + X x; + if(&x != dynamic_cast<X*>((B*)(CC*)(E*)&x)) error(20); //counter example + XX xx; + if(dynamic_cast<XX*>((B*)(CC*)(E*)&xx)) error(21); + Y y; + if(dynamic_cast<Y*>((B*)&y)) error (22); + if(dynamic_cast<Y*>((A*)(B*)&y)) error (23); +} + +// 2. crosscast + +struct J {virtual ~J(){};}; +struct K : CC, private J {}; +class KK : J, CC{}; + +void +test04 () +{ + E e; + if(dynamic_cast<CC*> ((B*)(D*)&e)) error(24); + if((CC*)&e != dynamic_cast<CC*> ((C*)(D*)&e)) error(25); //counter example + K k; + if(dynamic_cast<J*> ((B*)&k)) error(26); + KK kk; + if(dynamic_cast<J*> ((CC*)&kk)) error(27); +} + +int +main () +{ + test01(); + test02(); + test03(); + test04(); + return errors ? 1 : 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/dyncast2.C b/gcc/testsuite/g++.old-deja/g++.other/dyncast2.C new file mode 100644 index 0000000000000000000000000000000000000000..da537500b4d1c756f34a5889e592f60128e4e250 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast2.C @@ -0,0 +1,84 @@ +// Author: Alfred Miniarik <a8601248@unet.univie.ac.at> +// test of dynamic_cast +// runtime detecting of valid +// downcasts within nonpublic +// baseclasses. + +extern "C" void abort(); +extern "C" void printf(const char*, ...); + +static int errors = 0; + +void error(int i) +{ + printf("Error %i\n",i); + errors++; +} + +// 1. downcast +// 1.1 single inheritance case + +struct A {virtual ~A(){};int i;}; +struct B : A {int i;}; +struct C : B {int i;}; +struct CC : C {}; +class D : C {int i;}; + +struct E : D {int i;}; +class F : E {int i;}; + +void +test01 () +{ + D d; + if((C*)&d != dynamic_cast<C*> ((A*)&d)) error(1); + if((C*)&d != dynamic_cast<C*> ((B*)&d)) error(2); + if((B*)&d != dynamic_cast<B*> ((A*)&d)) error(3); + + E e; + if((C*)&e != dynamic_cast<C*> ((A*)&e)) error(4); + + F f; + if((C*)&f != dynamic_cast<C*> ((B*)&f)) error(5); + if((B*)&f != dynamic_cast<B*> ((A*)&f)) error(6); + if((E*)&f != dynamic_cast<E*> ((D*)&f)) error(7); + if(dynamic_cast<E*> ((C*)&f)) error(8); //counter example +} + +// 1.2 multiple inheritance case + +struct G : CC, F{}; + +void +test02 () +{ + G g; + if((B*)(F*)&g != dynamic_cast<B*> ((A*)(F*)&g)) error(9); + if(dynamic_cast<D*> ((A*)(F*)&g)) error(10); + if(dynamic_cast<G*> ((B*)(F*)&g)) error(11); +} + +// 2. crosscast (always fail) + +struct I : C{}; +struct J : F{}; +struct K : I, J{}; +class L : K{}; + +void +test03 () +{ + L l; + if(dynamic_cast<J*> ((I*)&l)) error(12); + if(dynamic_cast<J*> ((E*)&l)) error(13); + if(dynamic_cast<I*> ((J*)&l)) error(14); +} + +int +main () +{ + test01(); + test02(); + test03(); + return errors ? 1 : 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/dyncast3.C b/gcc/testsuite/g++.old-deja/g++.other/dyncast3.C new file mode 100644 index 0000000000000000000000000000000000000000..76f8ca7ed1a3c244ef54fed34c4bd024a85bda9f --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast3.C @@ -0,0 +1,32 @@ +// Author: Alfred Miniarik <a8601248@unet.univie.ac.at> +// test of dynamic_cast +// runtime detecting of nonpublic +// inheritance within a cast +// and therefor failing with result 0. + +extern "C" void abort(); +extern "C" void printf(const char*, ...); + +static int errors = 0; + +void error(int i) +{ + printf("Error %i\n",i); + errors++; +} + +struct A {virtual ~A(){}}; +struct B : private virtual A {}; +struct C : virtual A {}; +struct D : B, C {}; + +int +main() +{ + D d; + A* ap= &d; + if(&d != dynamic_cast<D*>(ap)) error(1); + if((B*)&d != dynamic_cast<B*>(ap)) error(2); + if((C*)&d != dynamic_cast<C*>(ap)) error(3); + return errors ? 1 : 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/dyncast4.C b/gcc/testsuite/g++.old-deja/g++.other/dyncast4.C new file mode 100644 index 0000000000000000000000000000000000000000..65093d568ffe0e00c58e3dc4f753b4d76cf725bc --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast4.C @@ -0,0 +1,27 @@ +// Author: Alfred Miniarik <a8601248@unet.univie.ac.at> + +// Even in a derived class, a private base cannot be dynamically downcasted +// from. + +extern "C" void abort(); + +struct A { + virtual ~A () {} +}; + +struct B : private A { + B* a2b (A* objp) + { + return dynamic_cast<B*> (objp); + } +}; + +int +main () +{ + B b; + A* aptr = (A*) &b; + if (dynamic_cast <B*> (aptr)) abort (); + if (b.a2b (aptr)) abort(); + return 0; +} diff --git a/gcc/testsuite/g++.old-deja/g++.other/dyncast5.C b/gcc/testsuite/g++.old-deja/g++.other/dyncast5.C new file mode 100644 index 0000000000000000000000000000000000000000..65a28523ec1fcf99346810fcc5e80387fc5f85ff --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast5.C @@ -0,0 +1,35 @@ +// Copyright (C) 1999 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 6 Jun 1999 <nathan@acm.org> + +// dynamic cast can only cast to public unambiguous bases + +struct A {virtual ~A(){} int m; }; +struct B {virtual ~B(){} int m; }; + +struct C1 : A {int m;}; +struct C2 : A {int m;}; + +// A is ambiguous, but private in one branch +struct D1 : B, C1, private C2 {int m;}; +// A is ambiguous, and public in both branches +struct D2 : B, C1, C2 {int m;}; + +void fn(B *bd1, B *bd2) +{ + A *ad1; + A *ad2; + + ad1 = dynamic_cast<A *>(bd1); + if(ad1) abort(); + ad2 = dynamic_cast<A *>(bd2); + if(ad2) abort(); +} + +int main() +{ + D1 d1; + D2 d2; + + fn((B *)&d1, (B *)&d2); + return 0; +}