diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 810fa52e71c..e2248aa7b25 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2000-08-17 Nathan Sidwell + + * inc/cxxabi.h (__cxa_vec_new2, __cxa_vec_new3): Declare. + (__cxa_vec_delete2, __cxa_vec_delete3): Declare. + * vec.cc (__cxa_vec_new2, __cxa_vec_new3): Implement. + (__cxa_vec_delete2, __cxa_vec_delete3): Implement. + (__cxa_vec_new): Use __cxa_vec_new2. + (__cxa_vec_delete): Use __cxa_vec_delete2. + 2000-08-17 Nathan Sidwell * vec.cc (__cxa_vec_new): Set "C" linkage. diff --git a/gcc/cp/inc/cxxabi.h b/gcc/cp/inc/cxxabi.h index 2a7217faf2b..908d7c467fe 100644 --- a/gcc/cp/inc/cxxabi.h +++ b/gcc/cp/inc/cxxabi.h @@ -437,6 +437,24 @@ void *__cxa_vec_new (__SIZE_TYPE__ __element_count, void (*__constructor) (void *), void (*__destructor) (void *)); +extern "C" +void *__cxa_vec_new2 (__SIZE_TYPE__ __element_count, + __SIZE_TYPE__ __element_size, + __SIZE_TYPE__ __padding_size, + void (*__constructor) (void *), + void (*__destructor) (void *), + void *(*__alloc) (__SIZE_TYPE__), + void (*__dealloc) (void *)); + +extern "C" +void *__cxa_vec_new3 (__SIZE_TYPE__ __element_count, + __SIZE_TYPE__ __element_size, + __SIZE_TYPE__ __padding_size, + void (*__constructor) (void *), + void (*__destructor) (void *), + void *(*__alloc) (__SIZE_TYPE__), + void (*__dealloc) (void *, __SIZE_TYPE__)); + /* construct array */ extern "C" void __cxa_vec_ctor (void *__array_address, @@ -467,6 +485,20 @@ void __cxa_vec_delete (void *__array_address, __SIZE_TYPE__ __padding_size, void (*__destructor) (void *)); +extern "C" +void __cxa_vec_delete2 (void *__array_address, + __SIZE_TYPE__ __element_size, + __SIZE_TYPE__ __padding_size, + void (*__destructor) (void *), + void (*__dealloc) (void *)); + +extern "C" +void __cxa_vec_delete3 (void *__array_address, + __SIZE_TYPE__ __element_size, + __SIZE_TYPE__ __padding_size, + void (*__destructor) (void *), + void (*__dealloc) (void *, __SIZE_TYPE__)); + /* demangling routines */ extern "C" diff --git a/gcc/cp/vec.cc b/gcc/cp/vec.cc index 83185978bb7..966feb486de 100644 --- a/gcc/cp/vec.cc +++ b/gcc/cp/vec.cc @@ -46,9 +46,23 @@ __cxa_vec_new (size_t element_count, size_t padding_size, void (*constructor) (void *), void (*destructor) (void *)) +{ + return __cxa_vec_new2 (element_count, element_size, padding_size, + constructor, destructor, + &operator new[], &operator delete []); +} + +extern "C" void * +__cxa_vec_new2 (size_t element_count, + size_t element_size, + size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *), + void *(*alloc) (size_t), + void (*dealloc) (void *)) { size_t size = element_count * element_size + padding_size; - char *base = static_cast (operator new[] (size)); + char *base = static_cast (alloc (size)); if (padding_size) { @@ -62,8 +76,39 @@ __cxa_vec_new (size_t element_count, } catch (...) { - // operator delete [] cannot throw, so no need to protect it - operator delete[] (base - padding_size); + __uncatch_exception (); + dealloc (base - padding_size); + throw; + } + return base; +} + +extern "C" void * +__cxa_vec_new3 (size_t element_count, + size_t element_size, + size_t padding_size, + void (*constructor) (void *), + void (*destructor) (void *), + void *(*alloc) (size_t), + void (*dealloc) (void *, size_t)) +{ + size_t size = element_count * element_size + padding_size; + char *base = static_cast (alloc (size)); + + if (padding_size) + { + base += padding_size; + reinterpret_cast (base)[-1] = element_count; + } + try + { + __cxa_vec_ctor (base, element_count, element_size, + constructor, destructor); + } + catch (...) + { + __uncatch_exception (); + dealloc (base - padding_size, size); throw; } return base; @@ -150,7 +195,7 @@ __cxa_vec_dtor (void *array_address, { if (unwinding) // [except.ctor]/3 If a destructor called during stack unwinding - // exists with an exception, terminate is called. + // exits with an exception, terminate is called. std::terminate (); __uncatch_exception (); __cxa_vec_dtor (array_address, ix, element_size, destructor); @@ -165,6 +210,18 @@ __cxa_vec_delete (void *array_address, size_t element_size, size_t padding_size, void (*destructor) (void *)) +{ + __cxa_vec_delete2 (array_address, element_size, padding_size, + destructor, + &operator delete []); +} + +extern "C" void +__cxa_vec_delete2 (void *array_address, + size_t element_size, + size_t padding_size, + void (*destructor) (void *), + void (*dealloc) (void *)) { char *base = static_cast (array_address); @@ -179,12 +236,42 @@ __cxa_vec_delete (void *array_address, } catch (...) { - // operator delete [] cannot throw, so no need to protect it - operator delete[] (base); + __uncatch_exception (); + dealloc (base); throw; } } - operator delete[] (base); + dealloc (base); +} + +extern "C" void +__cxa_vec_delete3 (void *array_address, + size_t element_size, + size_t padding_size, + void (*destructor) (void *), + void (*dealloc) (void *, size_t)) +{ + char *base = static_cast (array_address); + size_t size = 0; + + if (padding_size) + { + size_t element_count = reinterpret_cast (base)[-1]; + base -= padding_size; + size = element_count * element_size + padding_size; + try + { + __cxa_vec_dtor (array_address, element_count, element_size, + destructor); + } + catch (...) + { + __uncatch_exception (); + dealloc (base, size); + throw; + } + } + dealloc (base, size); } } // namespace __cxxabiv1