This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libstdc++ PATCH for c++/41174, c++/59224, Core DR 475


DR 475 clarified that uncaught_exception shouldn't return true until we are done creating the exception object and enter the unwinder:

http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#475

Fixed by moving the adjustment of the uncaughtExceptions count from the allocation to the throw.

Tested x86_64-pc-linux-gnu, applying to trunk and 4.8.
commit 97c1a72915840d1d466c228f0bcb13ee8e006acc
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Jan 24 13:52:44 2014 -0500

    	Core DR 475
    	PR c++/41174
    	PR c++/59224
    	* libsupc++/eh_throw.cc (__cxa_throw): Set uncaughtExceptions.
    	* libsupc++/eh_alloc.cc (__cxa_allocate_dependent_exception)
    	(__cxa_allocate_exception): Don't set it here.

diff --git a/gcc/testsuite/g++.dg/eh/uncaught1.C b/gcc/testsuite/g++.dg/eh/uncaught1.C
index afbf5af4..e96af33 100644
--- a/gcc/testsuite/g++.dg/eh/uncaught1.C
+++ b/gcc/testsuite/g++.dg/eh/uncaught1.C
@@ -13,7 +13,7 @@ struct Check {
 
 static Check const data[] = {
   { 0, 0, false },	// construct [0]
-  { 1, 0, true  },	// [1] = [0]
+  { 1, 0, false  },	// [1] = [0]
   { 0, 0, true  },	// destruct [0]
   { 2, 1, true  },	// [2] = [1]
   { 2, 2, true  },      // destruct [2]
diff --git a/gcc/testsuite/g++.dg/eh/uncaught4.C b/gcc/testsuite/g++.dg/eh/uncaught4.C
new file mode 100644
index 0000000..227d11b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/uncaught4.C
@@ -0,0 +1,29 @@
+// PR c++/41174
+// { dg-do run }
+
+#include <exception>
+
+#define assert(E) if (!(E)) __builtin_abort();
+
+struct e {
+  e()
+  {
+    assert( !std::uncaught_exception() );
+    try {
+      throw 1;
+    } catch (int i) {
+      assert( !std::uncaught_exception() );
+      throw;
+    }
+  }
+};
+
+int main()
+{
+  try {
+    throw e();
+  } catch (int i) {
+    assert( !std::uncaught_exception() );
+  }
+  assert( !std::uncaught_exception() );
+}
diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc
index 01eed97..752f5db 100644
--- a/libstdc++-v3/libsupc++/eh_alloc.cc
+++ b/libstdc++-v3/libsupc++/eh_alloc.cc
@@ -129,12 +129,6 @@ __cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) _GLIBCXX_NOTHROW
 	std::terminate ();
     }
 
-  // We have an uncaught exception as soon as we allocate memory.  This
-  // yields uncaught_exception() true during the copy-constructor that
-  // initializes the exception object.  See Issue 475.
-  __cxa_eh_globals *globals = __cxa_get_globals ();
-  globals->uncaughtExceptions += 1;
-
   memset (ret, 0, sizeof (__cxa_refcounted_exception));
 
   return (void *)((char *)ret + sizeof (__cxa_refcounted_exception));
@@ -191,12 +185,6 @@ __cxxabiv1::__cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW
 	std::terminate ();
     }
 
-  // We have an uncaught exception as soon as we allocate memory.  This
-  // yields uncaught_exception() true during the copy-constructor that
-  // initializes the exception object.  See Issue 475.
-  __cxa_eh_globals *globals = __cxa_get_globals ();
-  globals->uncaughtExceptions += 1;
-
   memset (ret, 0, sizeof (__cxa_dependent_exception));
 
   return ret;
diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc
index ffd28d8..e9a34e2 100644
--- a/libstdc++-v3/libsupc++/eh_throw.cc
+++ b/libstdc++-v3/libsupc++/eh_throw.cc
@@ -62,6 +62,9 @@ __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
 {
   PROBE2 (throw, obj, tinfo);
 
+  __cxa_eh_globals *globals = __cxa_get_globals ();
+  globals->uncaughtExceptions += 1;
+
   // Definitely a primary.
   __cxa_refcounted_exception *header
     = __get_refcounted_exception_header_from_obj (obj);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]