OSDN Git Service

* vec.cc: Include <new> and <exception>.
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 9 Apr 2000 16:05:16 +0000 (16:05 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 9 Apr 2000 16:05:16 +0000 (16:05 +0000)
(__cxa_vec_ctor): Use __cxa_vec_dtor for cleanup.
(__cxa_vec_dtor): Catch dtor exceptions, and rethrow or
terminate.
(__cxa_vec_delete): Catch dtor exceptions.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33042 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/vec.cc

index f76ef39..3457d8e 100644 (file)
@@ -1,5 +1,13 @@
 2000-04-09  Nathan Sidwell  <nathan@codesourcery.com>
 
+       * vec.cc: Include <new> and <exception>.
+       (__cxa_vec_ctor): Use __cxa_vec_dtor for cleanup.
+       (__cxa_vec_dtor): Catch dtor exceptions, and rethrow or
+       terminate.
+       (__cxa_vec_delete): Catch dtor exceptions.
+
+2000-04-09  Nathan Sidwell  <nathan@codesourcery.com>
+
        Prepend __ to implementation defined names.
        * inc/typeinfo (type_info): Rename _name to __name.
        (type_info::type_info): Rename parameter.
index 3b5182c..4f5ce49 100644 (file)
 
 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
 #include <cxxabi.h>
+#include <new>
+#include <exception>
+
+// Exception handling hook, to mark current exception as not caught --
+// generally because we're about to rethrow it after some cleanup.
+extern "C" void __uncatch_exception (void);
 
 namespace __cxxabiv1
 {
@@ -54,6 +60,7 @@ __cxa_vec_new (size_t element_count,
     }
   catch (...)
     {
+      // operator delete [] cannot throw, so no need to protect it
       operator delete[] (base - padding_size);
       throw;
     }
@@ -79,18 +86,8 @@ __cxa_vec_ctor (void *array_address,
     }
   catch (...)
     {
-      try
-        {
-          if (destructor)
-            for (; ix--; ptr -= element_size)
-              destructor (ptr);
-        }
-      catch (...)
-        {
-          // [except.ctor]/3 If a destructor called during stack unwinding
-          // exists with an exception, terminate is called.
-          std::terminate ();
-        }
+      __uncatch_exception ();
+      __cxa_vec_dtor (array_address, ix, element_size, destructor);
       throw;
     }
 }
@@ -105,13 +102,28 @@ __cxa_vec_dtor (void *array_address,
   if (destructor)
     {
       char *ptr = static_cast <char *> (array_address);
+      size_t ix = element_count;
+      bool unwinding = std::uncaught_exception ();
       
       ptr += element_count * element_size;
       
-      for (size_t ix = element_count; ix--;)
+      try
+        {
+          while (ix--)
+            {
+              ptr -= element_size;
+              destructor (ptr);
+            }
+        }
+      catch (...)
         {
-          ptr -= element_size;
-          destructor (ptr);
+          if (unwinding)
+            // [except.ctor]/3 If a destructor called during stack unwinding
+            // exists with an exception, terminate is called.
+            std::terminate ();
+          __uncatch_exception ();
+          __cxa_vec_dtor (array_address, ix, element_size, destructor);
+          throw;
         }
     }
 }
@@ -128,9 +140,18 @@ __cxa_vec_delete (void *array_address,
   if (padding_size)
     {
       size_t element_count = reinterpret_cast <size_t *> (base)[-1];
-      
-      __cxa_vec_dtor (base, element_count, element_size, destructor);
       base -= padding_size;
+      try
+        {
+          __cxa_vec_dtor (array_address, element_count, element_size,
+                          destructor);
+        }
+      catch (...)
+        {
+          // operator delete [] cannot throw, so no need to protect it
+          operator delete[] (base);
+          throw;
+        }
     }
   operator delete[] (base);
 }