* 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.
From-SVN: r29546
+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.
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;
+}