diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-31 02:56:34 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-31 02:56:34 +0000 |
commit | f1bf9e978ee92a576bb2699db1b5e974542caff9 (patch) | |
tree | 90cff28282aff9e481151ddefc4808ecd0a2226d /libstdc++-v3/libsupc++ | |
parent | 0aa31c959fdd43e026e22ab68eeb814beda6bfe3 (diff) | |
download | gcc-f1bf9e978ee92a576bb2699db1b5e974542caff9.tar.gz |
PR c++/3719
* libsupc++/eh_personality.cc (__cxa_call_unexpected): Copy handler
data out of the exception struct before calling unexpectedHandler.
* g++.dg/eh/unexpected1.C: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51623 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/libsupc++')
-rw-r--r-- | libstdc++-v3/libsupc++/eh_personality.cc | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index 802b9e2ca30..35e93a3c473 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -439,7 +439,18 @@ __cxa_call_unexpected (void *exc_obj_in) ~end_catch_protect() { __cxa_end_catch(); } } end_catch_protect_obj; + lsda_header_info info; __cxa_exception *xh = __get_exception_header_from_ue (exc_obj); + const unsigned char *xh_lsda; + _Unwind_Sword xh_switch_value; + std::terminate_handler xh_terminate_handler; + + // If the unexpectedHandler rethrows the exception (e.g. to categorize it), + // it will clobber data about the current handler. So copy the data out now. + xh_lsda = xh->languageSpecificData; + xh_switch_value = xh->handlerSwitchValue; + xh_terminate_handler = xh->terminateHandler; + info.ttype_base = (_Unwind_Ptr) xh->catchTemp; try { __unexpected (xh->unexpectedHandler); } @@ -453,13 +464,11 @@ __cxa_call_unexpected (void *exc_obj_in) void *new_ptr = new_xh + 1; // We don't quite have enough stuff cached; re-parse the LSDA. - lsda_header_info info; - parse_lsda_header (0, xh->languageSpecificData, &info); - info.ttype_base = (_Unwind_Ptr) xh->catchTemp; + parse_lsda_header (0, xh_lsda, &info); // If this new exception meets the exception spec, allow it. if (check_exception_spec (&info, new_xh->exceptionType, - new_ptr, xh->handlerSwitchValue)) + new_ptr, xh_switch_value)) __throw_exception_again; // If the exception spec allows std::bad_exception, throw that. @@ -467,10 +476,10 @@ __cxa_call_unexpected (void *exc_obj_in) // bad_exception doesn't have virtual bases, that's OK; just pass 0. #ifdef __EXCEPTIONS const std::type_info &bad_exc = typeid (std::bad_exception); - if (check_exception_spec (&info, &bad_exc, 0, xh->handlerSwitchValue)) + if (check_exception_spec (&info, &bad_exc, 0, xh_switch_value)) throw std::bad_exception(); #endif // Otherwise, die. - __terminate(xh->terminateHandler); + __terminate (xh_terminate_handler); } } |