[C++ PATCH]: new abi cxa_vec routines

Nathan Sidwell nathan@codesourcery.com
Sun Apr 9 09:10:00 GMT 2000


Hi,
I've installed the attached which makes the new abi's cxa_vec routines
exception correct, and tests them for the expected behaviour.
Thanks to Jason for pointing out the errors.

booted & tested on i686-pc-linux-gnu

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-04-07  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.

Index: cp/vec.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/vec.cc,v
retrieving revision 1.1
diff -c -3 -p -r1.1 vec.cc
*** vec.cc	2000/04/06 11:53:29	1.1
--- vec.cc	2000/04/07 22:52:36
***************
*** 27,33 ****
--- 27,39 ----
  
  #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
  {
  
*************** __cxa_vec_new (size_t element_count,
*** 54,59 ****
--- 60,66 ----
      }
    catch (...)
      {
+       // operator delete [] cannot throw, so no need to protect it
        operator delete[] (base - padding_size);
        throw;
      }
*************** __cxa_vec_ctor (void *array_address,
*** 79,96 ****
      }
    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 ();
!         }
        throw;
      }
  }
--- 86,93 ----
      }
    catch (...)
      {
!       __uncatch_exception ();
!       __cxa_vec_dtor (array_address, ix, element_size, destructor);
        throw;
      }
  }
*************** __cxa_vec_dtor (void *array_address,
*** 105,117 ****
    if (destructor)
      {
        char *ptr = static_cast <char *> (array_address);
        
        ptr += element_count * element_size;
        
!       for (size_t ix = element_count; ix--;)
          {
!           ptr -= element_size;
!           destructor (ptr);
          }
      }
  }
--- 102,129 ----
    if (destructor)
      {
        char *ptr = static_cast <char *> (array_address);
+       size_t ix = element_count;
+       bool unwinding = std::uncaught_exception ();
        
        ptr += element_count * element_size;
        
!       try
!         {
!           while (ix--)
!             {
!               ptr -= element_size;
!               destructor (ptr);
!             }
!         }
!       catch (...)
          {
!           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;
          }
      }
  }
*************** __cxa_vec_delete (void *array_address,
*** 128,136 ****
    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;
      }
    operator delete[] (base);
  }
--- 140,157 ----
    if (padding_size)
      {
        size_t element_count = reinterpret_cast <size_t *> (base)[-1];
        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);
  }


More information about the Gcc-patches mailing list