aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/libsupc++
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-01-07 23:50:42 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2009-01-07 23:50:42 +0100
commitc4bca01b27554f8a68a9391b278788bc1092c21f (patch)
treec60d6aa70fbdd55088e82c165c1341adb947d48c /libstdc++-v3/libsupc++
parent1f93f6871ed8248e799690c7029cf1d5b12ff2f2 (diff)
downloadgcc-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.cc10
-rw-r--r--libstdc++-v3/libsupc++/eh_ptr.cc27
-rw-r--r--libstdc++-v3/libsupc++/eh_throw.cc32
-rw-r--r--libstdc++-v3/libsupc++/unwind-cxx.h28
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)
{