summaryrefslogtreecommitdiff
path: root/src/exception.cc
diff options
context:
space:
mode:
authorDavid Chisnall <dchisnall@pathscale.com>2011-09-20 16:42:30 +0100
committerDavid Chisnall <dchisnall@pathscale.com>2011-09-20 16:42:30 +0100
commit482805524fe0480c2e1ec879b2488917ac92d78e (patch)
tree40d3df5c061b5999a6b06cda52e3bd5db2380a08 /src/exception.cc
parenta24acdd2378f4cdb8c9e9202da4b076047814928 (diff)
downloadlibcxxrt-482805524fe0480c2e1ec879b2488917ac92d78e.tar.gz
libcxxrt-482805524fe0480c2e1ec879b2488917ac92d78e.tar.bz2
libcxxrt-482805524fe0480c2e1ec879b2488917ac92d78e.tar.xz
Fix bugs that the libc++ test suite found in the handling of dependent exceptions.
Diffstat (limited to 'src/exception.cc')
-rw-r--r--src/exception.cc48
1 files changed, 25 insertions, 23 deletions
diff --git a/src/exception.cc b/src/exception.cc
index 6823e1c..a5891b3 100644
--- a/src/exception.cc
+++ b/src/exception.cc
@@ -150,24 +150,9 @@ static __cxa_exception *exceptionFromPointer(void *ex)
static __cxa_exception *realExceptionFromException(__cxa_exception *ex)
{
if (!isDependentException(ex->unwindHeader.exception_class)) { return ex; }
- return exceptionFromPointer(((__cxa_dependent_exception*)ex)->primaryException);
+ return ((__cxa_exception*)(((__cxa_dependent_exception*)ex)->primaryException))-1;
}
-static void releaseException(__cxa_exception *exception)
-{
- if (isDependentException(exception->unwindHeader.exception_class))
- {
- __cxa_free_dependent_exception(exception+1);
- return;
- }
- if (__sync_sub_and_fetch(&exception->referenceCount, 1) == 0)
- {
- // __cxa_free_exception() expects to be passed the thrown object,
- // which immediately follows the exception, not the exception
- // itself
- __cxa_free_exception(exception+1);
- }
-}
namespace std
{
@@ -473,12 +458,29 @@ extern "C" void __cxa_free_exception(void *thrown_exception)
free_exception((char*)ex);
}
+static void releaseException(__cxa_exception *exception)
+{
+ if (isDependentException(exception->unwindHeader.exception_class))
+ {
+ __cxa_free_dependent_exception(exception+1);
+ return;
+ }
+ if (__sync_sub_and_fetch(&exception->referenceCount, 1) == 0)
+ {
+ // __cxa_free_exception() expects to be passed the thrown object,
+ // which immediately follows the exception, not the exception
+ // itself
+ __cxa_free_exception(exception+1);
+ }
+}
+
void __cxa_free_dependent_exception(void *thrown_exception)
{
__cxa_dependent_exception *ex = ((__cxa_dependent_exception*)thrown_exception) - 1;
+ assert(isDependentException(ex->unwindHeader.exception_class));
if (ex->primaryException)
{
- __cxa_free_exception(ex->primaryException);
+ releaseException(realExceptionFromException((__cxa_exception*)ex));
}
free_exception((char*)ex);
}
@@ -610,7 +612,7 @@ extern "C" void __cxa_rethrow_primary_exception(void* thrown_exception)
if (NULL == thrown_exception) { return; }
__cxa_exception *original = exceptionFromPointer(thrown_exception);
- __cxa_dependent_exception *ex = (__cxa_dependent_exception*)__cxa_allocate_dependent_exception();
+ __cxa_dependent_exception *ex = ((__cxa_dependent_exception*)__cxa_allocate_dependent_exception())-1;
ex->primaryException = thrown_exception;
__cxa_increment_exception_refcount(thrown_exception);
@@ -630,20 +632,21 @@ extern "C" void *__cxa_current_primary_exception(void)
if (0 == ex) { return NULL; }
ex = realExceptionFromException(ex);
__sync_fetch_and_add(&ex->referenceCount, 1);
- return ex;
+ return ex + 1;
}
extern "C" void __cxa_increment_exception_refcount(void* thrown_exception)
{
if (NULL == thrown_exception) { return; }
- __cxa_exception *ex = exceptionFromPointer(thrown_exception);
+ __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
if (isDependentException(ex->unwindHeader.exception_class)) { return; }
__sync_fetch_and_add(&ex->referenceCount, 1);
}
extern "C" void __cxa_decrement_exception_refcount(void* thrown_exception)
{
if (NULL == thrown_exception) { return; }
- releaseException(exceptionFromPointer(thrown_exception));
+ __cxa_exception *ex = ((__cxa_exception*)thrown_exception) - 1;
+ releaseException(ex);
}
/**
@@ -670,7 +673,6 @@ extern "C" void __cxa_rethrow()
std::terminate();
}
-
assert(ex->handlerCount > 0 && "Rethrowing uncaught exception!");
// ex->handlerCount will be decremented in __cxa_end_catch in enclosing
@@ -1019,7 +1021,7 @@ extern "C" void *__cxa_begin_catch(void *e)
globals->uncaughtExceptions--;
_Unwind_Exception *exceptionObject = (_Unwind_Exception*)e;
- if (exceptionObject->exception_class == exception_class)
+ if (isCXXException(exceptionObject->exception_class))
{
__cxa_exception *ex = exceptionFromPointer(exceptionObject);