summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/compat/eh
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/compat/eh
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/compat/eh')
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/ctor1.h10
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/ctor1_main.C13
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/ctor1_x.C22
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/ctor1_y.C13
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/ctor2.h22
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/ctor2_main.C12
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/ctor2_x.C19
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/ctor2_y.C20
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/dtor1.h7
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/dtor1_main.C14
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/dtor1_x.C14
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/dtor1_y.C18
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/filter1.h5
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/filter1_main.C11
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/filter1_x.C21
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/filter1_y.C17
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/filter2_main.C12
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/filter2_x.C22
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/filter2_y.C39
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/new1_main.C13
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/new1_x.C29
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/new1_y.C19
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/nrv1.h5
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/nrv1_main.C12
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/nrv1_x.C21
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/nrv1_y.C8
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/spec3.h8
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/spec3_main.C12
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/spec3_x.C9
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/spec3_y.C8
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/template1.h15
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/template1_main.C12
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/template1_x.C21
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/template1_y.C8
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/unexpected1_main.C12
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/unexpected1_x.C26
-rw-r--r--gcc/testsuite/g++.dg/compat/eh/unexpected1_y.C21
37 files changed, 570 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/compat/eh/ctor1.h b/gcc/testsuite/g++.dg/compat/eh/ctor1.h
new file mode 100644
index 000000000..e83476f2d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/ctor1.h
@@ -0,0 +1,10 @@
+struct Foo
+{
+ ~Foo ();
+};
+
+struct Bar
+{
+ ~Bar ();
+ Foo f;
+};
diff --git a/gcc/testsuite/g++.dg/compat/eh/ctor1_main.C b/gcc/testsuite/g++.dg/compat/eh/ctor1_main.C
new file mode 100644
index 000000000..a188b46da
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/ctor1_main.C
@@ -0,0 +1,13 @@
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 26 Dec 2001 <nathan@nathan@codesourcery.com>
+// PR 411
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void ctor1_x (void);
+
+int
+main ()
+{
+ ctor1_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/ctor1_x.C b/gcc/testsuite/g++.dg/compat/eh/ctor1_x.C
new file mode 100644
index 000000000..d74a52087
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/ctor1_x.C
@@ -0,0 +1,22 @@
+extern "C" void abort (void);
+extern "C" void exit (int);
+
+#include "ctor1.h"
+
+bool was_f_in_Bar_destroyed=false;
+
+void ctor1_x ()
+{
+ try
+ {
+ Bar f;
+ }
+ catch(int i)
+ {
+ if(was_f_in_Bar_destroyed)
+ {
+ exit (0);
+ }
+ }
+ abort ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/ctor1_y.C b/gcc/testsuite/g++.dg/compat/eh/ctor1_y.C
new file mode 100644
index 000000000..260ab1c34
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/ctor1_y.C
@@ -0,0 +1,13 @@
+extern bool was_f_in_Bar_destroyed;
+
+#include "ctor1.h"
+
+Foo::~Foo()
+{
+ was_f_in_Bar_destroyed=true;
+}
+
+Bar::~Bar()
+{
+ throw 1;
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/ctor2.h b/gcc/testsuite/g++.dg/compat/eh/ctor2.h
new file mode 100644
index 000000000..c6b9f40f8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/ctor2.h
@@ -0,0 +1,22 @@
+struct VBase
+{
+ virtual void f () {}
+ VBase();
+ ~VBase();
+};
+
+struct StreamBase
+{
+ virtual ~StreamBase() {}
+};
+
+struct Stream : public virtual VBase, public StreamBase
+{
+ Stream();
+ virtual ~Stream() {}
+};
+
+struct DerivedStream : public Stream
+{
+ DerivedStream();
+};
diff --git a/gcc/testsuite/g++.dg/compat/eh/ctor2_main.C b/gcc/testsuite/g++.dg/compat/eh/ctor2_main.C
new file mode 100644
index 000000000..58836e26e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/ctor2_main.C
@@ -0,0 +1,12 @@
+// PR c++/4460
+// Test that the cleanup for fully-constructed subobjects when a
+// constructor throws gets the right address for a virtual base.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void ctor2_x (void);
+
+int main ()
+{
+ ctor2_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/ctor2_x.C b/gcc/testsuite/g++.dg/compat/eh/ctor2_x.C
new file mode 100644
index 000000000..3fa1a53ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/ctor2_x.C
@@ -0,0 +1,19 @@
+extern "C" void exit (int);
+extern "C" void abort (void);
+
+#include "ctor2.h"
+
+int r;
+
+void ctor2_x () {
+
+ try
+ {
+ DerivedStream str;
+ }
+ catch (...) { }
+
+ if (r != 0)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/ctor2_y.C b/gcc/testsuite/g++.dg/compat/eh/ctor2_y.C
new file mode 100644
index 000000000..00ba92000
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/ctor2_y.C
@@ -0,0 +1,20 @@
+extern int r;
+void *p;
+
+#include "ctor2.h"
+
+VBase::VBase ()
+{
+ p = this;
+}
+
+VBase::~VBase ()
+{
+ if (p != this) r = 1;
+}
+
+Stream::Stream () {}
+DerivedStream::DerivedStream ()
+{
+ throw 1;
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/dtor1.h b/gcc/testsuite/g++.dg/compat/eh/dtor1.h
new file mode 100644
index 000000000..0dfa793e0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/dtor1.h
@@ -0,0 +1,7 @@
+struct A {
+ ~A();
+};
+
+struct B: public A {
+ ~B();
+};
diff --git a/gcc/testsuite/g++.dg/compat/eh/dtor1_main.C b/gcc/testsuite/g++.dg/compat/eh/dtor1_main.C
new file mode 100644
index 000000000..962fa6427
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/dtor1_main.C
@@ -0,0 +1,14 @@
+// PR c++/411
+
+// Test that a fully-constructed base is destroyed before transferring
+// control to the handler of a function-try-block.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void dtor1_x (void);
+
+int
+main ()
+{
+ dtor1_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/dtor1_x.C b/gcc/testsuite/g++.dg/compat/eh/dtor1_x.C
new file mode 100644
index 000000000..f7f4cc8a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/dtor1_x.C
@@ -0,0 +1,14 @@
+extern "C" void exit (int);
+extern "C" void abort (void);
+
+#include "dtor1.h"
+
+int r;
+
+void dtor1_x ()
+{
+ { B b; }
+ if (r != 0)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/dtor1_y.C b/gcc/testsuite/g++.dg/compat/eh/dtor1_y.C
new file mode 100644
index 000000000..a1ec41a27
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/dtor1_y.C
@@ -0,0 +1,18 @@
+extern int r;
+int ad;
+
+#include "dtor1.h"
+
+A::~A () { ++ad; }
+
+B::~B ()
+try
+ {
+ throw 1;
+ }
+catch (...)
+ {
+ if (!ad)
+ r = 1;
+ return;
+ }
diff --git a/gcc/testsuite/g++.dg/compat/eh/filter1.h b/gcc/testsuite/g++.dg/compat/eh/filter1.h
new file mode 100644
index 000000000..1f5f0c936
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/filter1.h
@@ -0,0 +1,5 @@
+struct a
+{
+ a();
+ ~a();
+};
diff --git a/gcc/testsuite/g++.dg/compat/eh/filter1_main.C b/gcc/testsuite/g++.dg/compat/eh/filter1_main.C
new file mode 100644
index 000000000..2a8fca42c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/filter1_main.C
@@ -0,0 +1,11 @@
+// Test that cleanups get run when a catch filter fails to match.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void filter1_x (void);
+
+int
+main ()
+{
+ filter1_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/filter1_x.C b/gcc/testsuite/g++.dg/compat/eh/filter1_x.C
new file mode 100644
index 000000000..b3789aa15
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/filter1_x.C
@@ -0,0 +1,21 @@
+#include "filter1.h"
+
+extern "C" void exit (int);
+extern "C" void abort (void);
+extern void ex_test (void);
+
+void
+filter1_x ()
+{
+ try
+ {
+ ex_test ();
+ }
+ catch (...)
+ {
+ }
+ abort ();
+}
+
+a::a() { }
+a::~a() { exit (0); }
diff --git a/gcc/testsuite/g++.dg/compat/eh/filter1_y.C b/gcc/testsuite/g++.dg/compat/eh/filter1_y.C
new file mode 100644
index 000000000..48de0877d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/filter1_y.C
@@ -0,0 +1,17 @@
+#include "filter1.h"
+
+struct e1 {};
+struct e2 {};
+
+void
+ex_test ()
+{
+ a aa;
+ try
+ {
+ throw e1 ();
+ }
+ catch (e2 &)
+ {
+ }
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/filter2_main.C b/gcc/testsuite/g++.dg/compat/eh/filter2_main.C
new file mode 100644
index 000000000..866199c6b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/filter2_main.C
@@ -0,0 +1,12 @@
+// Test that terminate gets run when a catch filter fails to match while
+// running destructors. Original bug depended on a::~a being inlined.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void filter2_x (void);
+
+int
+main ()
+{
+ filter2_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/filter2_x.C b/gcc/testsuite/g++.dg/compat/eh/filter2_x.C
new file mode 100644
index 000000000..287ffc7bd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/filter2_x.C
@@ -0,0 +1,22 @@
+#include <exception>
+#include <cstdlib>
+
+extern "C" void abort (void);
+
+extern void my_terminate (void);
+extern void ex_test (void);
+
+void
+filter2_x ()
+{
+ std::set_terminate (my_terminate);
+
+ try
+ {
+ ex_test ();
+ }
+ catch (...)
+ {
+ }
+ abort ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/filter2_y.C b/gcc/testsuite/g++.dg/compat/eh/filter2_y.C
new file mode 100644
index 000000000..87c6fea10
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/filter2_y.C
@@ -0,0 +1,39 @@
+#include <exception>
+#include <cstdlib>
+
+struct e1 {};
+struct e2 {};
+
+struct a
+{
+ a () { }
+
+ ~a ()
+ {
+ try
+ {
+ throw e1();
+ }
+ catch (e2 &)
+ {
+ }
+ }
+};
+
+void
+ex_test ()
+{
+ a aa;
+ try
+ {
+ throw e1 ();
+ }
+ catch (e2 &)
+ {
+ }
+}
+
+void my_terminate ()
+{
+ std::exit (0);
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/new1_main.C b/gcc/testsuite/g++.dg/compat/eh/new1_main.C
new file mode 100644
index 000000000..ee4cad8e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/new1_main.C
@@ -0,0 +1,13 @@
+// PR c++/5757
+// Test that when a constructor throws in a new-expression, we pass the
+// right pointer to operator delete.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void new1_x (void);
+
+int
+main ()
+{
+ new1_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/new1_x.C b/gcc/testsuite/g++.dg/compat/eh/new1_x.C
new file mode 100644
index 000000000..121287170
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/new1_x.C
@@ -0,0 +1,29 @@
+#include <new>
+#include <cstddef>
+
+extern "C" void exit (int);
+extern "C" void abort (void);
+
+extern void * operator new[] (std::size_t s) throw (std::bad_alloc);
+extern void operator delete[] (void *p) throw ();
+
+struct A
+{
+ A() { throw 1; }
+ ~A() {}
+};
+
+int ret = 1;
+
+void
+new1_x ()
+{
+ try
+ {
+ A *p = new A[4];
+ }
+ catch (...) {}
+ if (ret != 0)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/new1_y.C b/gcc/testsuite/g++.dg/compat/eh/new1_y.C
new file mode 100644
index 000000000..fbe0e2145
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/new1_y.C
@@ -0,0 +1,19 @@
+#include <new>
+#include <cstddef>
+
+extern int ret;
+
+void *ptr;
+void * operator new[] (std::size_t s) throw (std::bad_alloc)
+{
+ ptr = operator new (s);
+ return ptr;
+}
+
+void operator delete[] (void *p) throw ()
+{
+ if (p == ptr)
+ ret = 0;
+ operator delete (p);
+}
+
diff --git a/gcc/testsuite/g++.dg/compat/eh/nrv1.h b/gcc/testsuite/g++.dg/compat/eh/nrv1.h
new file mode 100644
index 000000000..853ea3914
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/nrv1.h
@@ -0,0 +1,5 @@
+struct A
+{
+ A();
+ ~A();
+};
diff --git a/gcc/testsuite/g++.dg/compat/eh/nrv1_main.C b/gcc/testsuite/g++.dg/compat/eh/nrv1_main.C
new file mode 100644
index 000000000..3b76b5c88
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/nrv1_main.C
@@ -0,0 +1,12 @@
+// PR c++/5636
+// Bug: the named return value optimization interfered with EH cleanups.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void nrv1_x (void);
+
+int
+main ()
+{
+ nrv1_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/nrv1_x.C b/gcc/testsuite/g++.dg/compat/eh/nrv1_x.C
new file mode 100644
index 000000000..0647de889
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/nrv1_x.C
@@ -0,0 +1,21 @@
+extern "C" void exit (int);
+extern "C" void abort (void);
+
+#include "nrv1.h"
+
+extern A f (void);
+
+int c, d;
+
+void nrv1_x ()
+{
+ try
+ { A a = f(); }
+ catch (...) { }
+ if (d < c)
+ abort ();
+ exit (0);
+}
+
+A::A() { ++c; }
+A::~A() { ++d; }
diff --git a/gcc/testsuite/g++.dg/compat/eh/nrv1_y.C b/gcc/testsuite/g++.dg/compat/eh/nrv1_y.C
new file mode 100644
index 000000000..5a43af7c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/nrv1_y.C
@@ -0,0 +1,8 @@
+#include "nrv1.h"
+
+A f()
+{
+ A nrv;
+ throw 42;
+ return nrv;
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/spec3.h b/gcc/testsuite/g++.dg/compat/eh/spec3.h
new file mode 100644
index 000000000..a042c1004
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/spec3.h
@@ -0,0 +1,8 @@
+class Base {};
+
+struct A : virtual public Base
+{
+ A();
+};
+
+struct B {};
diff --git a/gcc/testsuite/g++.dg/compat/eh/spec3_main.C b/gcc/testsuite/g++.dg/compat/eh/spec3_main.C
new file mode 100644
index 000000000..3f0e919b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/spec3_main.C
@@ -0,0 +1,12 @@
+// PR c++/4381
+// Test that exception-specs work properly for classes with virtual bases.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void spec3_x (void);
+
+int
+main ()
+{
+ spec3_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/spec3_x.C b/gcc/testsuite/g++.dg/compat/eh/spec3_x.C
new file mode 100644
index 000000000..b8e5fbeaa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/spec3_x.C
@@ -0,0 +1,9 @@
+#include "spec3.h"
+
+extern void func () throw (B,A);
+
+void spec3_x (void)
+{
+ try { func(); }
+ catch (A& a) { }
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/spec3_y.C b/gcc/testsuite/g++.dg/compat/eh/spec3_y.C
new file mode 100644
index 000000000..fef6b368c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/spec3_y.C
@@ -0,0 +1,8 @@
+#include "spec3.h"
+
+A::A() {}
+
+void func() throw (B,A)
+{
+ throw A();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/template1.h b/gcc/testsuite/g++.dg/compat/eh/template1.h
new file mode 100644
index 000000000..93999a11d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/template1.h
@@ -0,0 +1,15 @@
+class A {};
+
+template <class T>
+struct B
+{
+ typedef A E;
+};
+
+template <class T>
+struct C
+{
+ typedef B<T> D;
+ typedef typename D::E E;
+ void f() throw(E);
+};
diff --git a/gcc/testsuite/g++.dg/compat/eh/template1_main.C b/gcc/testsuite/g++.dg/compat/eh/template1_main.C
new file mode 100644
index 000000000..2d169808c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/template1_main.C
@@ -0,0 +1,12 @@
+// Test whether exception specifier dependent on template parameter
+// is accepted during template decl processing.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void template1_x (void);
+
+int
+main ()
+{
+ template1_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/template1_x.C b/gcc/testsuite/g++.dg/compat/eh/template1_x.C
new file mode 100644
index 000000000..5a18be789
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/template1_x.C
@@ -0,0 +1,21 @@
+extern "C" void exit (int);
+extern "C" void abort (void);
+
+#include "template1.h"
+
+void template1_x ()
+{
+ int caught = 0;
+ try
+ {
+ C<int> x;
+ x.f();
+ }
+ catch (A)
+ {
+ ++caught;
+ }
+ if (caught != 1)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/template1_y.C b/gcc/testsuite/g++.dg/compat/eh/template1_y.C
new file mode 100644
index 000000000..19425375c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/template1_y.C
@@ -0,0 +1,8 @@
+#include "template1.h"
+
+template<class T> void C<T>::f (void) throw (E)
+{
+ throw E();
+}
+
+template class C<int>;
diff --git a/gcc/testsuite/g++.dg/compat/eh/unexpected1_main.C b/gcc/testsuite/g++.dg/compat/eh/unexpected1_main.C
new file mode 100644
index 000000000..1658db77e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/unexpected1_main.C
@@ -0,0 +1,12 @@
+// PR 3719
+// Test that an unexpected handler can rethrow to categorize.
+
+// Split into pieces for binary compatibility testing October 2002
+
+extern void unexpected1_x ();
+
+int
+main ()
+{
+ unexpected1_x ();
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/unexpected1_x.C b/gcc/testsuite/g++.dg/compat/eh/unexpected1_x.C
new file mode 100644
index 000000000..61361a68d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/unexpected1_x.C
@@ -0,0 +1,26 @@
+#include <exception>
+
+struct One { };
+struct Two { };
+
+extern "C" void abort ();
+extern void doit (void) throw (Two);
+extern void handle_unexpected (void);
+
+void
+unexpected1_x ()
+{
+ std::set_unexpected (handle_unexpected);
+
+ try
+ {
+ doit ();
+ }
+ catch (Two &)
+ {
+ }
+ catch (...)
+ {
+ abort ();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/compat/eh/unexpected1_y.C b/gcc/testsuite/g++.dg/compat/eh/unexpected1_y.C
new file mode 100644
index 000000000..0c42c4579
--- /dev/null
+++ b/gcc/testsuite/g++.dg/compat/eh/unexpected1_y.C
@@ -0,0 +1,21 @@
+struct One { };
+struct Two { };
+
+void
+handle_unexpected ()
+{
+ try
+ {
+ throw;
+ }
+ catch (One &)
+ {
+ throw Two ();
+ }
+}
+
+void
+doit () throw (Two)
+{
+ throw One ();
+}