[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