diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b2255e837ef..65639f39ea8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,25 @@ +Tue Sep 21 15:38:10 BST 1999 Nathan Sidwell + + * 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 * 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 00000000000..0451d77ca7f --- /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 + +// 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 00000000000..33873aa3cbe --- /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 + +// 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 00000000000..94c602c7e0a --- /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 + +// 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 00000000000..19c2273ec56 --- /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 + +// 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 00000000000..9dff637ade1 --- /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 + +// 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 00000000000..c6a5d0a0b1f --- /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 + +// 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 00000000000..1ac48124c98 --- /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 + +// 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 00000000000..3aac1a789cc --- /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 + +// 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 00000000000..bf90e0e590b --- /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 + +// 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 00000000000..be017c1a10b --- /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 + +// 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 00000000000..685a4ec7d7f --- /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 + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// D--B--A +// +--C< + +// We cannot catch an ambiguous base class. +// -- public, << private, == virtual + +// D--B--A +// +--C< + +// 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 00000000000..ff7bf302d84 --- /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 + +// 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 00000000000..0a3a09b9a12 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast1.C @@ -0,0 +1,122 @@ +// Author: Alfred Miniarik +// 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 ((A*)&d)) error(1); + if(dynamic_cast ((B*)&d)) error(2); + if(&d != dynamic_cast ((C*)&d)) error(3); //counter example + if(dynamic_cast ((B*)&d)) error(4); + + DD dd; + if(dynamic_cast ((A*)&dd)) error(5); + if(dynamic_cast ((B*)&dd)) error(6); + + DDD ddd; + if(dynamic_cast ((A*)&ddd)) error(7); + if(dynamic_cast ((B*)&ddd)) error(8); + if(dynamic_cast ((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 ((A*)(D*)&e)) error(10); + if(dynamic_cast ((B*)(D*)&e)) error(11); + if(&e != dynamic_cast ((C*)(D*)&e)) error(12); //counter example + if(&e != dynamic_cast ((B*)(CC*)&e)) error(13); //counter example + if((CC*)&e != dynamic_cast ((B*)(CC*)&e)) error(14); //counter example + + EE ee; + if(dynamic_cast ((A*)(D*)&ee)) error(15); + if(dynamic_cast ((B*)(D*)&ee)) error(16); + if(&ee != dynamic_cast ((C*)(D*)&ee)) error(17); //counter example + if(&ee != dynamic_cast ((B*)(CC*)&ee)) error(18); //counter example + if((CC*)&ee != dynamic_cast ((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((B*)(CC*)(E*)&x)) error(20); //counter example + XX xx; + if(dynamic_cast((B*)(CC*)(E*)&xx)) error(21); + Y y; + if(dynamic_cast((B*)&y)) error (22); + if(dynamic_cast((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 ((B*)(D*)&e)) error(24); + if((CC*)&e != dynamic_cast ((C*)(D*)&e)) error(25); //counter example + K k; + if(dynamic_cast ((B*)&k)) error(26); + KK kk; + if(dynamic_cast ((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 00000000000..da537500b4d --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast2.C @@ -0,0 +1,84 @@ +// Author: Alfred Miniarik +// 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 ((A*)&d)) error(1); + if((C*)&d != dynamic_cast ((B*)&d)) error(2); + if((B*)&d != dynamic_cast ((A*)&d)) error(3); + + E e; + if((C*)&e != dynamic_cast ((A*)&e)) error(4); + + F f; + if((C*)&f != dynamic_cast ((B*)&f)) error(5); + if((B*)&f != dynamic_cast ((A*)&f)) error(6); + if((E*)&f != dynamic_cast ((D*)&f)) error(7); + if(dynamic_cast ((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 ((A*)(F*)&g)) error(9); + if(dynamic_cast ((A*)(F*)&g)) error(10); + if(dynamic_cast ((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 ((I*)&l)) error(12); + if(dynamic_cast ((E*)&l)) error(13); + if(dynamic_cast ((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 00000000000..76f8ca7ed1a --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast3.C @@ -0,0 +1,32 @@ +// Author: Alfred Miniarik +// 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(ap)) error(1); + if((B*)&d != dynamic_cast(ap)) error(2); + if((C*)&d != dynamic_cast(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 00000000000..65093d568ff --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/dyncast4.C @@ -0,0 +1,27 @@ +// Author: Alfred Miniarik + +// 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 (objp); + } +}; + +int +main () +{ + B b; + A* aptr = (A*) &b; + if (dynamic_cast (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 00000000000..65a28523ec1 --- /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 + +// 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(bd1); + if(ad1) abort(); + ad2 = dynamic_cast(bd2); + if(ad2) abort(); +} + +int main() +{ + D1 d1; + D2 d2; + + fn((B *)&d1, (B *)&d2); + return 0; +}