summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoranonymous <local@localhost>2010-06-30 12:42:13 +0000
committeranonymous <local@localhost>2010-06-30 12:42:13 +0000
commit3fdd328c6cc79830f1635ed3126d042aad265297 (patch)
tree6cf138376ab1fad357ee6e9a30413ba51a6722ef /src
parentf2b9158f2813c948617c2c8ef6c0f653c1aa5f10 (diff)
downloadlibcxxrt-3fdd328c6cc79830f1635ed3126d042aad265297.tar.gz
libcxxrt-3fdd328c6cc79830f1635ed3126d042aad265297.tar.bz2
libcxxrt-3fdd328c6cc79830f1635ed3126d042aad265297.tar.xz
Add a proper cleanup handler, to allow foreign exception handlers to
destroy this exception.
Diffstat (limited to 'src')
-rw-r--r--src/exception.cc16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/exception.cc b/src/exception.cc
index 5bfd921..ce06435 100644
--- a/src/exception.cc
+++ b/src/exception.cc
@@ -133,6 +133,16 @@ static pthread_key_t eh_key;
extern "C" void __cxa_free_exception(void *thrown_exception);
/**
+ * Cleanup function, allowing foreign exception handlers to correctly destroy
+ * this exception if they catch it.
+ */
+static void exception_cleanup(_Unwind_Reason_Code reason,
+ struct _Unwind_Exception *ex)
+{
+ __cxa_free_exception((void*)ex);
+}
+
+/**
* Recursively walk a list of exceptions and delete them all in post-order.
*/
static void free_exception_list(__cxa_exception *ex)
@@ -439,6 +449,7 @@ extern "C" void __cxa_throw(void *thrown_exception,
ex->exceptionDestructor = dest;
ex->unwindHeader.exception_class = exception_class;
+ ex->unwindHeader.exception_cleanup = exception_cleanup;
info->globals.uncaughtExceptions++;
@@ -584,12 +595,9 @@ static bool check_action_record(_Unwind_Context *context,
dw_eh_ptr_t action_record_offset_base = action_record;
int displacement = read_sleb128(&action_record);
*selector = filter;
- // TODO: Negative offset = exception spec
- // TOCO: 0 = catchall
// We only check handler types for C++ exceptions - foreign exceptions
// are only allowed for cleanup.
- // // FIXME: foreign exception if catchall
- if (filter > 0 && 0 != ex)
+ if (filter > 0 && 0 != ex)
{
std::type_info *handler_type = get_type_info_entry(context, lsda, filter);
if (check_type_signature(ex, handler_type))