dyncast1.C: New test.
authorNathan Sidwell <nathan@acm.org>
Tue, 21 Sep 1999 15:00:41 +0000 (15:00 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 21 Sep 1999 15:00:41 +0000 (15:00 +0000)
* 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

20 files changed:
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.eh/catch3.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch3p.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch4.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch4p.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch5.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch5p.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch6.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch6p.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch7.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch7p.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch8.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch8p.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch9.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.eh/catch9p.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/dyncast1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/dyncast2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/dyncast3.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/dyncast4.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/dyncast5.C [new file with mode: 0644]

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