diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-01-07 23:50:42 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2009-01-07 23:50:42 +0100 |
commit | c4bca01b27554f8a68a9391b278788bc1092c21f (patch) | |
tree | c60d6aa70fbdd55088e82c165c1341adb947d48c /libstdc++-v3/libsupc++ | |
parent | 1f93f6871ed8248e799690c7029cf1d5b12ff2f2 (diff) | |
download | gcc-c4bca01b27554f8a68a9391b278788bc1092c21f.zip gcc-c4bca01b27554f8a68a9391b278788bc1092c21f.tar.gz gcc-c4bca01b27554f8a68a9391b278788bc1092c21f.tar.bz2 |
re PR libstdc++/38732 (Openoffice.org segfaults with runtime libs built from GCC trunk)
PR libstdc++/38732
* libsupc++/unwind-cxx.h (__cxxabiv1::__cxa_exception): Remove
referenceCount field again.
(__cxxabiv1::__cxa_refcounted_exception): New struct.
(__cxxabiv1::__get_refcounted_exception_header_from_obj,
__cxxabiv1::__get_refcounted_exception_header_from_ue): New static
inline functions.
* libsupc++/eh_alloc.cc (__cxxabiv1::__cxa_allocate_exception,
__cxxabiv1::__cxa_free_exception): Use __cxa_refcounted_exception
instead of __cxa_exception.
* libsupc++/eh_throw.cc (__gxx_exception_cleanup,
__cxxabiv1::__cxa_throw): Likewise.
* libsupc++/eh_ptr.cc (std::rethrow_exception,
std::__exception_ptr::exception_ptr::_M_addref,
std::__exception_ptr::exception_ptr::_M_release,
__gxx_dependent_exception_cleanup): Likewise.
* testsuite/18_support/exception/38732.cc: New test.
From-SVN: r143170
Diffstat (limited to 'libstdc++-v3/libsupc++')
-rw-r--r-- | libstdc++-v3/libsupc++/eh_alloc.cc | 10 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/eh_ptr.cc | 27 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/eh_throw.cc | 32 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/unwind-cxx.h | 28 |
4 files changed, 60 insertions, 37 deletions
diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc index 6bc46fc..495a25f 100644 --- a/libstdc++-v3/libsupc++/eh_alloc.cc +++ b/libstdc++-v3/libsupc++/eh_alloc.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Allocate exception objects. -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 // Free Software Foundation, Inc. // // This file is part of GCC. @@ -103,7 +103,7 @@ __cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw() { void *ret; - thrown_size += sizeof (__cxa_exception); + thrown_size += sizeof (__cxa_refcounted_exception); ret = malloc (thrown_size); if (! ret) @@ -137,9 +137,9 @@ __cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw() __cxa_eh_globals *globals = __cxa_get_globals (); globals->uncaughtExceptions += 1; - memset (ret, 0, sizeof (__cxa_exception)); + memset (ret, 0, sizeof (__cxa_refcounted_exception)); - return (void *)((char *)ret + sizeof (__cxa_exception)); + return (void *)((char *)ret + sizeof (__cxa_refcounted_exception)); } @@ -158,7 +158,7 @@ __cxxabiv1::__cxa_free_exception(void *vptr) throw() emergency_used &= ~((bitmask_type)1 << which); } else - free (ptr - sizeof (__cxa_exception)); + free (ptr - sizeof (__cxa_refcounted_exception)); } diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index 901219a..414a6b9 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Implement the members of exception_ptr. -// Copyright (C) 2008 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -84,8 +84,8 @@ std::__exception_ptr::exception_ptr::_M_addref() throw() { if (_M_exception_object) { - __cxa_exception *eh = - __get_exception_header_from_obj (_M_exception_object); + __cxa_refcounted_exception *eh = + __get_refcounted_exception_header_from_obj (_M_exception_object); __sync_add_and_fetch (&eh->referenceCount, 1); } } @@ -96,12 +96,12 @@ std::__exception_ptr::exception_ptr::_M_release() throw() { if (_M_exception_object) { - __cxa_exception *eh = - __get_exception_header_from_obj (_M_exception_object); + __cxa_refcounted_exception *eh = + __get_refcounted_exception_header_from_obj (_M_exception_object); if (__sync_sub_and_fetch (&eh->referenceCount, 1) == 0) { - if (eh->exceptionDestructor) - eh->exceptionDestructor (_M_exception_object); + if (eh->exc.exceptionDestructor) + eh->exc.exceptionDestructor (_M_exception_object); __cxa_free_exception (_M_exception_object); _M_exception_object = 0; @@ -191,22 +191,22 @@ __gxx_dependent_exception_cleanup (_Unwind_Reason_Code code, { // This cleanup is set only for dependents. __cxa_dependent_exception *dep = __get_dependent_exception_from_ue (exc); - __cxa_exception *header = - __get_exception_header_from_obj (dep->primaryException); + __cxa_refcounted_exception *header = + __get_refcounted_exception_header_from_obj (dep->primaryException); // We only want to be called through _Unwind_DeleteException. // _Unwind_DeleteException in the HP-UX IA64 libunwind library // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT // like the GCC _Unwind_DeleteException function does. if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) - __terminate (header->terminateHandler); + __terminate (header->exc.terminateHandler); __cxa_free_dependent_exception (dep); if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) { - if (header->exceptionDestructor) - header->exceptionDestructor (header + 1); + if (header->exc.exceptionDestructor) + header->exc.exceptionDestructor (header + 1); __cxa_free_exception (header + 1); } @@ -217,7 +217,8 @@ void std::rethrow_exception(std::exception_ptr ep) { void *obj = ep._M_get(); - __cxa_exception *eh = __get_exception_header_from_obj (obj); + __cxa_refcounted_exception *eh + = __get_refcounted_exception_header_from_obj (obj); __cxa_dependent_exception *dep = __cxa_allocate_dependent_exception (); dep->primaryException = obj; diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index 24b3577..afe7c68 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling routines for throwing. -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 // Free Software Foundation, Inc. // // This file is part of GCC. @@ -38,21 +38,22 @@ static void __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) { // This cleanup is set only for primaries. - __cxa_exception *header = __get_exception_header_from_ue (exc); + __cxa_refcounted_exception *header + = __get_refcounted_exception_header_from_ue (exc); // We only want to be called through _Unwind_DeleteException. // _Unwind_DeleteException in the HP-UX IA64 libunwind library // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT // like the GCC _Unwind_DeleteException function does. if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) - __terminate (header->terminateHandler); + __terminate (header->exc.terminateHandler); #ifdef _GLIBCXX_ATOMIC_BUILTINS_4 if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) { #endif - if (header->exceptionDestructor) - header->exceptionDestructor (header + 1); + if (header->exc.exceptionDestructor) + header->exc.exceptionDestructor (header + 1); __cxa_free_exception (header + 1); #ifdef _GLIBCXX_ATOMIC_BUILTINS_4 @@ -66,23 +67,24 @@ __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, void (*dest) (void *)) { // Definitely a primary. - __cxa_exception *header = __get_exception_header_from_obj (obj); + __cxa_refcounted_exception *header + = __get_refcounted_exception_header_from_obj (obj); header->referenceCount = 1; - header->exceptionType = tinfo; - header->exceptionDestructor = dest; - header->unexpectedHandler = __unexpected_handler; - header->terminateHandler = __terminate_handler; - __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->unwindHeader.exception_class); - header->unwindHeader.exception_cleanup = __gxx_exception_cleanup; + header->exc.exceptionType = tinfo; + header->exc.exceptionDestructor = dest; + header->exc.unexpectedHandler = __unexpected_handler; + header->exc.terminateHandler = __terminate_handler; + __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class); + header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup; #ifdef _GLIBCXX_SJLJ_EXCEPTIONS - _Unwind_SjLj_RaiseException (&header->unwindHeader); + _Unwind_SjLj_RaiseException (&header->exc.unwindHeader); #else - _Unwind_RaiseException (&header->unwindHeader); + _Unwind_RaiseException (&header->exc.unwindHeader); #endif // Some sort of unwinding error. Note that terminate is a handler. - __cxa_begin_catch (&header->unwindHeader); + __cxa_begin_catch (&header->exc.unwindHeader); std::terminate (); } diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h index 3f6a765..3e2cf0f 100644 --- a/libstdc++-v3/libsupc++/unwind-cxx.h +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling and frame unwind runtime interface routines. -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 // Free Software Foundation, Inc. // // This file is part of GCC. @@ -53,9 +53,6 @@ namespace __cxxabiv1 struct __cxa_exception { - // Manage this header. - _Atomic_word referenceCount; - // Manage the exception object itself. std::type_info *exceptionType; void (*exceptionDestructor)(void *); @@ -92,6 +89,14 @@ struct __cxa_exception _Unwind_Exception unwindHeader; }; +struct __cxa_refcounted_exception +{ + // Manage this header. + _Atomic_word referenceCount; + // __cxa_exception must be last, and no padding can be after it. + __cxa_exception exc; +}; + // A dependent C++ exception object consists of a wrapper around an unwind // object header with additional C++ specific information, containing a pointer // to a primary exception object. @@ -227,6 +232,21 @@ __get_exception_header_from_ue (_Unwind_Exception *exc) return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; } +// Acquire the C++ refcounted exception header from the C++ object. +static inline __cxa_refcounted_exception * +__get_refcounted_exception_header_from_obj (void *ptr) +{ + return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1; +} + +// Acquire the C++ refcounted exception header from the generic exception +// header. +static inline __cxa_refcounted_exception * +__get_refcounted_exception_header_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1; +} + static inline __cxa_dependent_exception * __get_dependent_exception_from_ue (_Unwind_Exception *exc) { |