summaryrefslogtreecommitdiff
path: root/src/exception.cc
diff options
context:
space:
mode:
authoranonymous <local@localhost>2011-01-06 05:36:17 +0600
committeranonymous <local@localhost>2011-01-06 05:36:17 +0600
commita41c5557e2da79f03873a232189cb1a569424394 (patch)
tree3474a06d2802d8f31b0c152642ce8bf0ede00283 /src/exception.cc
parentaca9afa6aa45f18979da31391902933f7da65e27 (diff)
downloadlibcxxrt-a41c5557e2da79f03873a232189cb1a569424394.tar.gz
libcxxrt-a41c5557e2da79f03873a232189cb1a569424394.tar.bz2
libcxxrt-a41c5557e2da79f03873a232189cb1a569424394.tar.xz
Fix for COMPILER-8909
Diffstat (limited to 'src/exception.cc')
-rw-r--r--src/exception.cc23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/exception.cc b/src/exception.cc
index 3920cf7..9c4bc4d 100644
--- a/src/exception.cc
+++ b/src/exception.cc
@@ -774,7 +774,17 @@ extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version,
if (actions & _UA_SEARCH_PHASE)
{
struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr);
- action = dwarf_eh_find_callsite(context, &lsda);
+ if (!dwarf_eh_find_callsite(context, &lsda, &action))
+ {
+ // EH range not found. This happens if exception is thrown
+ // and not catched inside cleanup (destructor).
+ // We should call terminate() in this case
+ // catchTemp (landing pad) field of exception object will
+ // contain null when personality function will be called
+ // with _UA_HANDLER_FRAME action
+ return _URC_HANDLER_FOUND;
+ }
+
handler_type found_handler = check_action_record(context, &lsda,
action.action_record, ex, &selector);
// If there's no action record, we've only found a cleanup, so keep
@@ -803,18 +813,25 @@ extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version,
// context for a cleanup.
if (!(actions & _UA_HANDLER_FRAME))
{
+ // cleanup
+
struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr);
- action = dwarf_eh_find_callsite(context, &lsda);
+ dwarf_eh_find_callsite(context, &lsda, &action);
if (0 == action.landing_pad) { return _URC_CONTINUE_UNWIND; }
handler_type found_handler = check_action_record(context, &lsda,
action.action_record, ex, &selector);
// Ignore handlers this time.
if (found_handler != handler_cleanup) { return _URC_CONTINUE_UNWIND; }
}
+ else if (ex->catchTemp == 0)
+ {
+ // uncaught exception in claenup, calling terminate
+ std::terminate();
+ }
else if (foreignException)
{
struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr);
- action = dwarf_eh_find_callsite(context, &lsda);
+ dwarf_eh_find_callsite(context, &lsda, &action);
check_action_record(context, &lsda, action.action_record, ex,
&selector);
}