aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog10
-rw-r--r--libstdc++-v3/libsupc++/eh_arm.cc43
-rw-r--r--libstdc++-v3/libsupc++/eh_personality.cc14
-rw-r--r--libstdc++-v3/libsupc++/eh_throw.cc2
4 files changed, 48 insertions, 21 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0fa5039..f84cefd 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,13 @@
+2005-11-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * libsupc++/eh_arm.cc (__cxa_begin_cleanup): Remember a
+ foreign exception too.
+ (__gnu_end_cleanup): Recover a foreign exception too.
+ * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Cope
+ with forced unwinding.
+ * libsupc++/eh_throw.cc (__cxxabiv1::__cxa_rethrow): Use
+ _Unwind_Resume_or_Rethrow for ARM EABI.
+
2005-11-14 Geoffrey Keating <geoffk@apple.com>
* acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Don't check for
diff --git a/libstdc++-v3/libsupc++/eh_arm.cc b/libstdc++-v3/libsupc++/eh_arm.cc
index d87d82a..269b2ec 100644
--- a/libstdc++-v3/libsupc++/eh_arm.cc
+++ b/libstdc++-v3/libsupc++/eh_arm.cc
@@ -89,20 +89,31 @@ __cxa_begin_cleanup(_Unwind_Exception* ue_header)
{
__cxa_eh_globals *globals = __cxa_get_globals();
__cxa_exception *header = __get_exception_header_from_ue(ue_header);
+ bool native = __is_gxx_exception_class(header->unwindHeader.exception_class);
- if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
+
+ if (native)
{
- // TODO: cleanups with foreign exceptions.
- return false;
+ header->propagationCount++;
+ // Add it to the chain if this is the first time we've seen this
+ // exception.
+ if (header->propagationCount == 1)
+ {
+ header->nextPropagatingException = globals->propagatingExceptions;
+ globals->propagatingExceptions = header;
+ }
}
- header->propagationCount++;
- // Add it to the chain if this is the first time we've seen this exception.
- if (header->propagationCount == 1)
+ else
{
- header->nextPropagatingException = globals->propagatingExceptions;
+ // Remember the exception object, so end_cleanup can return it.
+ // These cannot be stacked, so we must abort if we already have
+ // a propagating exception.
+ if (globals->propagatingExceptions)
+ std::terminate ();
globals->propagatingExceptions = header;
}
- return true;
+
+ return !native;
}
// Do the work for __cxa_end_cleanup. Returns the currently propagating
@@ -119,13 +130,19 @@ __gnu_end_cleanup(void)
if (!header)
std::terminate();
- header->propagationCount--;
- if (header->propagationCount == 0)
+ if (__is_gxx_exception_class(header->unwindHeader.exception_class))
{
- // Remove exception from chain.
- globals->propagatingExceptions = header->nextPropagatingException;
- header->nextPropagatingException = NULL;
+ header->propagationCount--;
+ if (header->propagationCount == 0)
+ {
+ // Remove exception from chain.
+ globals->propagatingExceptions = header->nextPropagatingException;
+ header->nextPropagatingException = NULL;
+ }
}
+ else
+ globals->propagatingExceptions = NULL;
+
return &header->unwindHeader;
}
diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc
index 6205851..f07864f 100644
--- a/libstdc++-v3/libsupc++/eh_personality.cc
+++ b/libstdc++-v3/libsupc++/eh_personality.cc
@@ -369,7 +369,7 @@ PERSONALITY_FUNCTION (int version,
#ifdef __ARM_EABI_UNWINDER__
_Unwind_Action actions;
- switch (state)
+ switch (state & _US_ACTION_MASK)
{
case _US_VIRTUAL_UNWIND_FRAME:
actions = _UA_SEARCH_PHASE;
@@ -377,7 +377,8 @@ PERSONALITY_FUNCTION (int version,
case _US_UNWIND_FRAME_STARTING:
actions = _UA_CLEANUP_PHASE;
- if (ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13))
+ if (!(state & _US_FORCE_UNWIND)
+ && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13))
actions |= _UA_HANDLER_FRAME;
break;
@@ -388,6 +389,7 @@ PERSONALITY_FUNCTION (int version,
default:
abort();
}
+ actions |= state & _US_FORCE_UNWIND;
// We don't know which runtime we're working with, so can't check this.
// However the ABI routines hide this from us, and we don't actually need
@@ -523,13 +525,13 @@ PERSONALITY_FUNCTION (int version,
// exception class, there's no exception type.
// ??? What to do about GNU Java and GNU Ada exceptions.
-#ifdef __ARM_EABI_UNWINDER__
- throw_type = ue_header;
-#else
if ((actions & _UA_FORCE_UNWIND)
|| foreign_exception)
throw_type = 0;
else
+#ifdef __ARM_EABI_UNWINDER__
+ throw_type = ue_header;
+#else
throw_type = xh->exceptionType;
#endif
@@ -613,7 +615,6 @@ PERSONALITY_FUNCTION (int version,
install_context:
-#ifndef __ARM_EABI_UNWINDER__
// We can't use any of the cxa routines with foreign exceptions,
// because they all expect ue_header to be a struct __cxa_exception.
// So in that case, call terminate or unexpected directly.
@@ -631,7 +632,6 @@ PERSONALITY_FUNCTION (int version,
}
}
else
-#endif
{
if (found_type == found_terminate)
__cxa_call_terminate(ue_header);
diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc
index 8b04f39..9f26be0 100644
--- a/libstdc++-v3/libsupc++/eh_throw.cc
+++ b/libstdc++-v3/libsupc++/eh_throw.cc
@@ -97,7 +97,7 @@ __cxxabiv1::__cxa_rethrow ()
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
_Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader);
#else
-#if defined(_LIBUNWIND_STD_ABI) || defined (__ARM_EABI_UNWINDER__)
+#if defined(_LIBUNWIND_STD_ABI)
_Unwind_RaiseException (&header->unwindHeader);
#else
_Unwind_Resume_or_Rethrow (&header->unwindHeader);