New test
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Jul 2009 17:08:50 +0000 (17:08 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Jul 2009 17:08:50 +0000 (17:08 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149715 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/eh4.C [new file with mode: 0644]

index 859a5e9..558a0b9 100644 (file)
@@ -1,3 +1,7 @@
+2009-07-16  Richard Henderson  <rth@redhat.com>
+
+       * g++.dg/opt/eh4.C: New test.
+
 2009-07-16  Jakub Jelinek  <jakub@redhat.com>
 
        * obj-c++.dg/defs.mm (abort): Make it extern "C".
diff --git a/gcc/testsuite/g++.dg/opt/eh4.C b/gcc/testsuite/g++.dg/opt/eh4.C
new file mode 100644 (file)
index 0000000..0a62ee2
--- /dev/null
@@ -0,0 +1,59 @@
+// { dg-do run }
+// { dg-options "-O3" }
+
+// Make sure that the call to terminate within F2 is not eliminated
+// by incorrect MUST_NOT_THROW optimization.  Note that we expect F1
+// to be inlined into F2 in order to expose this case.
+
+#include <cstdlib>
+#include <exception>
+
+static volatile int zero = 0;
+
+// Note that we need F0 to not be marked nothrow, though we don't actually
+// want a throw to happen at runtime here.  The noinline tag is merely to
+// make sure the assembly in F0 is not unnecessarily complex.
+static void __attribute__((noinline)) f0()
+{
+  if (zero != 0)
+    throw 0;
+}
+
+struct S1
+{
+  S1() { }
+  ~S1() { f0(); }
+};
+
+static void f1()
+{
+  S1 s1;
+  throw 1;
+}
+
+struct S2
+{
+  S2() { }
+  ~S2() { f1(); }
+};
+
+static void __attribute__((noinline)) f2()
+{
+  S2 s2;
+  throw 2;
+}
+
+static void pass()
+{
+  exit (0);
+}
+
+int main()
+{
+  std::set_terminate (pass);
+  try {
+    f2();
+  } catch (...) {
+  }
+  abort ();
+}