From ec001bc92887d66331bf22047ee0c8ee26100c6c Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 13 Aug 2008 20:08:55 +0000 Subject: [PATCH] 2008-08-13 Paolo Carlini Revert the last patch. From-SVN: r139074 --- libstdc++-v3/ChangeLog | 4 + libstdc++-v3/config/abi/pre/gnu.ver | 29 +-- libstdc++-v3/libsupc++/Makefile.am | 3 +- libstdc++-v3/libsupc++/Makefile.in | 9 +- libstdc++-v3/libsupc++/eh_alloc.cc | 68 +---- libstdc++-v3/libsupc++/eh_arm.cc | 8 +- libstdc++-v3/libsupc++/eh_call.cc | 4 +- libstdc++-v3/libsupc++/eh_personality.cc | 22 +- libstdc++-v3/libsupc++/eh_ptr.cc | 236 ------------------ libstdc++-v3/libsupc++/eh_throw.cc | 21 +- libstdc++-v3/libsupc++/eh_type.cc | 12 +- libstdc++-v3/libsupc++/exception | 7 +- libstdc++-v3/libsupc++/exception_ptr.h | 169 ------------- libstdc++-v3/libsupc++/unwind-cxx.h | 142 +---------- .../exception_ptr/current_exception.cc | 90 ------- .../18_support/exception_ptr/lifespan.cc | 188 -------------- .../exception_ptr/rethrow_exception.cc | 113 --------- 17 files changed, 47 insertions(+), 1078 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a0928ede3f64..2edf9f9d2eab 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,7 @@ +2008-08-13 Paolo Carlini + + Revert the last patch. + 2008-08-13 Sebastian Redl Add exception propagation support as per N2179. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 0ec4879ffd4e..7b31a1cfa472 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -66,9 +66,7 @@ GLIBCXX_3.4 { # std::condition_variable; std::co[^n]*; std::c[p-s]*; - std::cu[^r]*; -# std::current_exception - std::c[v-z]*; + std::c[u-z]*; # std::[d-g]*; std::d[a-d]*; std::d[f-z]*; @@ -114,13 +112,10 @@ GLIBCXX_3.4 { std::n[^au]*; std::nu[^m]*; std::num[^e]*; + std::[p-r]*; std::ostrstream*; std::out_of_range*; std::overflow_error*; - std::[p-q]*; - std::r[^e]*; - std::re[^t]*; -# std::rethrow_exception std::set_new_handler*; std::set_terminate*; std::set_unexpected*; @@ -1052,24 +1047,4 @@ CXXABI_1.3.3 { _ZTIPu8char32_t; _ZTIPKu8char32_t; - # exception_ptr - _ZNSt15__exception_ptr13exception_ptrC1Ev; - _ZNSt15__exception_ptr13exception_ptrC2Ev; - _ZNSt15__exception_ptr13exception_ptrC1ERKS0_; - _ZNSt15__exception_ptr13exception_ptrC2ERKS0_; - _ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE; - _ZNSt15__exception_ptr13exception_ptrC2EMS0_FvvE; - _ZNSt15__exception_ptr13exception_ptrD1Ev; - _ZNSt15__exception_ptr13exception_ptrD2Ev; - _ZNSt15__exception_ptr13exception_ptraSERKS0_; - _ZNKSt15__exception_ptr13exception_ptrcvMS0_FvvEEv; - _ZNKSt15__exception_ptr13exception_ptrntEv; - _ZNKSt15__exception_ptr13exception_ptr20__cxa_exception_typeEv; - _ZNSt15__exception_ptr13exception_ptr4swapERS0_; - _ZNSt15__exception_ptreqERKNS_13exception_ptrES2_; - _ZNSt15__exception_ptrneERKNS_13exception_ptrES2_; - - _ZSt17current_exceptionv; - _ZSt17rethrow_exceptionNSt15__exception_ptr13exception_ptrE; - } CXXABI_1.3.2; diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am index 680005fbf83b..c0412f0b8ed5 100644 --- a/libstdc++-v3/libsupc++/Makefile.am +++ b/libstdc++-v3/libsupc++/Makefile.am @@ -34,7 +34,7 @@ noinst_LTLIBRARIES = libsupc++convenience.la headers = \ exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \ - initializer_list exception_ptr.h + initializer_list if GLIBCXX_HOSTED c_sources = \ @@ -60,7 +60,6 @@ sources = \ eh_exception.cc \ eh_globals.cc \ eh_personality.cc \ - eh_ptr.cc \ eh_term_handler.cc \ eh_terminate.cc \ eh_throw.cc \ diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in index c3d1c6c6b432..105aec63d8dd 100644 --- a/libstdc++-v3/libsupc++/Makefile.in +++ b/libstdc++-v3/libsupc++/Makefile.in @@ -79,7 +79,7 @@ am__libsupc___la_SOURCES_DIST = array_type_info.cc atexit_arm.cc \ bad_cast.cc bad_typeid.cc class_type_info.cc del_op.cc \ del_opnt.cc del_opv.cc del_opvnt.cc dyncast.cc eh_alloc.cc \ eh_arm.cc eh_aux_runtime.cc eh_call.cc eh_catch.cc \ - eh_exception.cc eh_globals.cc eh_personality.cc eh_ptr.cc \ + eh_exception.cc eh_globals.cc eh_personality.cc \ eh_term_handler.cc eh_terminate.cc eh_throw.cc eh_type.cc \ eh_unex_handler.cc enum_type_info.cc function_type_info.cc \ fundamental_type_info.cc guard.cc new_handler.cc new_op.cc \ @@ -91,7 +91,7 @@ am__objects_1 = array_type_info.lo atexit_arm.lo bad_cast.lo \ bad_typeid.lo class_type_info.lo del_op.lo del_opnt.lo \ del_opv.lo del_opvnt.lo dyncast.lo eh_alloc.lo eh_arm.lo \ eh_aux_runtime.lo eh_call.lo eh_catch.lo eh_exception.lo \ - eh_globals.lo eh_personality.lo eh_ptr.lo eh_term_handler.lo \ + eh_globals.lo eh_personality.lo eh_term_handler.lo \ eh_terminate.lo eh_throw.lo eh_type.lo eh_unex_handler.lo \ enum_type_info.lo function_type_info.lo \ fundamental_type_info.lo guard.lo new_handler.lo new_op.lo \ @@ -107,7 +107,7 @@ am__libsupc__convenience_la_SOURCES_DIST = array_type_info.cc \ atexit_arm.cc bad_cast.cc bad_typeid.cc class_type_info.cc \ del_op.cc del_opnt.cc del_opv.cc del_opvnt.cc dyncast.cc \ eh_alloc.cc eh_arm.cc eh_aux_runtime.cc eh_call.cc eh_catch.cc \ - eh_exception.cc eh_globals.cc eh_personality.cc eh_ptr.cc \ + eh_exception.cc eh_globals.cc eh_personality.cc \ eh_term_handler.cc eh_terminate.cc eh_throw.cc eh_type.cc \ eh_unex_handler.cc enum_type_info.cc function_type_info.cc \ fundamental_type_info.cc guard.cc new_handler.cc new_op.cc \ @@ -356,7 +356,7 @@ toolexeclib_LTLIBRARIES = libsupc++.la noinst_LTLIBRARIES = libsupc++convenience.la headers = \ exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \ - initializer_list exception_ptr.h + initializer_list @GLIBCXX_HOSTED_TRUE@c_sources = \ @GLIBCXX_HOSTED_TRUE@ cp-demangle.c @@ -380,7 +380,6 @@ sources = \ eh_exception.cc \ eh_globals.cc \ eh_personality.cc \ - eh_ptr.cc \ eh_term_handler.cc \ eh_terminate.cc \ eh_throw.cc \ diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc index 6bc46fc9a912..553c1c1e8580 100644 --- a/libstdc++-v3/libsupc++/eh_alloc.cc +++ b/libstdc++-v3/libsupc++/eh_alloc.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Allocate exception objects. -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 // Free Software Foundation, Inc. // // This file is part of GCC. @@ -89,9 +89,6 @@ typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned)); static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT]; static bitmask_type emergency_used; -static __cxa_dependent_exception dependents_buffer[EMERGENCY_OBJ_COUNT]; -static bitmask_type dependents_used; - namespace { // A single mutex controlling emergency allocations. @@ -160,66 +157,3 @@ __cxxabiv1::__cxa_free_exception(void *vptr) throw() else free (ptr - sizeof (__cxa_exception)); } - - -extern "C" __cxa_dependent_exception* -__cxxabiv1::__cxa_allocate_dependent_exception() throw() -{ - __cxa_dependent_exception *ret; - - ret = static_cast<__cxa_dependent_exception*> - (malloc (sizeof (__cxa_dependent_exception))); - - if (!ret) - { - __gnu_cxx::__scoped_lock sentry(emergency_mutex); - - bitmask_type used = dependents_used; - unsigned int which = 0; - - while (used & 1) - { - used >>= 1; - if (++which >= EMERGENCY_OBJ_COUNT) - goto failed; - } - - dependents_used |= (bitmask_type)1 << which; - ret = &dependents_buffer[which]; - - failed:; - - if (!ret) - std::terminate (); - } - - // We have an uncaught exception as soon as we allocate memory. This - // yields uncaught_exception() true during the copy-constructor that - // initializes the exception object. See Issue 475. - __cxa_eh_globals *globals = __cxa_get_globals (); - globals->uncaughtExceptions += 1; - - memset (ret, 0, sizeof (__cxa_dependent_exception)); - - return ret; -} - - -extern "C" void -__cxxabiv1::__cxa_free_dependent_exception - (__cxa_dependent_exception *vptr) throw() -{ - char *base = (char *) dependents_buffer; - char *ptr = (char *) vptr; - if (ptr >= base - && ptr < base + sizeof (dependents_buffer)) - { - const unsigned int which - = (unsigned) (ptr - base) / sizeof (__cxa_dependent_exception); - - __gnu_cxx::__scoped_lock sentry(emergency_mutex); - dependents_used &= ~((bitmask_type)1 << which); - } - else - free (vptr); -} diff --git a/libstdc++-v3/libsupc++/eh_arm.cc b/libstdc++-v3/libsupc++/eh_arm.cc index f10bb41e5c03..6f770e95663c 100644 --- a/libstdc++-v3/libsupc++/eh_arm.cc +++ b/libstdc++-v3/libsupc++/eh_arm.cc @@ -1,5 +1,5 @@ // -*- C++ -*- ARM specific Exception handling support routines. -// Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc. +// Copyright (C) 2004, 2005 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -48,19 +48,13 @@ __cxa_type_match(_Unwind_Exception* ue_header, { bool forced_unwind = __is_gxx_forced_unwind_class(ue_header->exception_class); bool foreign_exception = !forced_unwind && !__is_gxx_exception_class(ue_header->exception_class); - bool dependent_exception = - __is_dependent_exception(ue_header->exception_class); __cxa_exception* xh = __get_exception_header_from_ue(ue_header); - __cxa_dependent_exception *dx = __get_dependent_exception_from_ue(ue_header); const std::type_info* throw_type; if (forced_unwind) throw_type = &typeid(abi::__forced_unwind); else if (foreign_exception) throw_type = &typeid(abi::__foreign_exception); - else if (dependent_exception) - throw_type = __get_exception_header_from_obj - (dx->primaryException)->exceptionType; else throw_type = xh->exceptionType; diff --git a/libstdc++-v3/libsupc++/eh_call.cc b/libstdc++-v3/libsupc++/eh_call.cc index c0bced995331..edf62188a6b6 100644 --- a/libstdc++-v3/libsupc++/eh_call.cc +++ b/libstdc++-v3/libsupc++/eh_call.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Helpers for calling unextected and terminate -// Copyright (C) 2001, 2002, 2003, 2008 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -125,7 +125,7 @@ __cxa_call_unexpected(void* exc_obj_in) __cxa_eh_globals* globals = __cxa_get_globals_fast(); __cxa_exception* new_xh = globals->caughtExceptions; - void* new_ptr = __gxx_get_object_from_ambiguous_exception (new_xh); + void* new_ptr = new_xh + 1; const std::type_info* catch_type; int n; bool bad_exception_allowed = false; diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc index 12b54c16587d..b7d957c4d376 100644 --- a/libstdc++-v3/libsupc++/eh_personality.cc +++ b/libstdc++-v3/libsupc++/eh_personality.cc @@ -377,7 +377,7 @@ PERSONALITY_FUNCTION (int version, const unsigned char *p; _Unwind_Ptr landing_pad, ip; int handler_switch_value; - void* thrown_ptr = 0; + void* thrown_ptr = ue_header + 1; bool foreign_exception; int ip_before_insn = 0; @@ -543,33 +543,30 @@ PERSONALITY_FUNCTION (int version, bool saw_handler = false; #ifdef __ARM_EABI_UNWINDER__ - // ??? How does this work - more importantly, how does it interact with - // dependent exceptions? throw_type = ue_header; if (actions & _UA_FORCE_UNWIND) { __GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class); + thrown_ptr = 0; } - else if (!foreign_exception) - thrown_ptr = __get_object_from_ue (ue_header); + else if (foreign_exception) + thrown_ptr = 0; #else // During forced unwinding, match a magic exception type. if (actions & _UA_FORCE_UNWIND) { throw_type = &typeid(abi::__forced_unwind); + thrown_ptr = 0; } // With a foreign exception class, there's no exception type. // ??? What to do about GNU Java and GNU Ada exceptions? else if (foreign_exception) { throw_type = &typeid(abi::__foreign_exception); + thrown_ptr = 0; } else - { - thrown_ptr = __get_object_from_ue (ue_header); - throw_type = __get_exception_header_from_obj - (thrown_ptr)->exceptionType; - } + throw_type = xh->exceptionType; #endif while (1) @@ -761,14 +758,13 @@ __cxa_call_unexpected (void *exc_obj_in) __cxa_eh_globals *globals = __cxa_get_globals_fast (); __cxa_exception *new_xh = globals->caughtExceptions; - void *new_ptr = __get_object_from_ambiguous_exception (new_xh); + void *new_ptr = new_xh + 1; // We don't quite have enough stuff cached; re-parse the LSDA. parse_lsda_header (0, xh_lsda, &info); // If this new exception meets the exception spec, allow it. - if (check_exception_spec (&info, __get_exception_header_from_obj - (new_ptr)->exceptionType, + if (check_exception_spec (&info, new_xh->exceptionType, new_ptr, xh_switch_value)) __throw_exception_again; diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index 060b8eb2668f..e69de29bb2d1 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -1,236 +0,0 @@ -// -*- C++ -*- Implement the members of exception_ptr. -// Copyright (C) 2008 Free Software Foundation, Inc. -// -// This file is part of GCC. -// -// GCC is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// GCC is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING. If not, write to -// the Free Software Foundation, 51 Franklin Street, Fifth Floor, -// Boston, MA 02110-1301, USA. - -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -#include -#include -#include -#include "unwind-cxx.h" - -using namespace __cxxabiv1; - - -std::__exception_ptr::exception_ptr::exception_ptr() throw() - : _M_exception_object(0) -{ -} - - -std::__exception_ptr::exception_ptr::exception_ptr(void* obj) throw() - : _M_exception_object(obj) -{ - _M_addref(); -} - - -std::__exception_ptr::exception_ptr::exception_ptr(__safe_bool) throw() - : _M_exception_object(0) -{ -} - - -std::__exception_ptr::exception_ptr::exception_ptr( - const exception_ptr& other) throw() - : _M_exception_object(other._M_exception_object) -{ - _M_addref(); -} - - -std::__exception_ptr::exception_ptr::~exception_ptr() throw() -{ - _M_release(); -} - - -std::__exception_ptr::exception_ptr& -std::__exception_ptr::exception_ptr::operator=( - const exception_ptr& other) throw() -{ - exception_ptr(other).swap(*this); - return *this; -} - - -void -std::__exception_ptr::exception_ptr::_M_addref() throw() -{ - if (_M_exception_object) - { - __cxa_exception *eh = - __get_exception_header_from_obj (_M_exception_object); - __sync_add_and_fetch (&eh->referenceCount, 1); - } -} - - -void -std::__exception_ptr::exception_ptr::_M_release() throw() -{ - if (_M_exception_object) - { - __cxa_exception *eh = - __get_exception_header_from_obj (_M_exception_object); - if (__sync_sub_and_fetch (&eh->referenceCount, 1) == 0) - { - if (eh->exceptionDestructor) - eh->exceptionDestructor (_M_exception_object); - - __cxa_free_exception (_M_exception_object); - _M_exception_object = 0; - } - } -} - - -void* -std::__exception_ptr::exception_ptr::_M_get() const throw() -{ - return _M_exception_object; -} - - -void -std::__exception_ptr::exception_ptr::_M_safe_bool_dummy() -{ -} - - -void -std::__exception_ptr::exception_ptr::swap(exception_ptr &other) throw() -{ - void *tmp = _M_exception_object; - _M_exception_object = other._M_exception_object; - other._M_exception_object = tmp; -} - - -bool -std::__exception_ptr::exception_ptr::operator!() const throw() -{ - return _M_exception_object == 0; -} - - -std::__exception_ptr::exception_ptr::operator __safe_bool() const throw() -{ - return _M_exception_object ? &exception_ptr::_M_safe_bool_dummy : 0; -} - - -const std::type_info* -std::__exception_ptr::exception_ptr::__cxa_exception_type() const throw() -{ - __cxa_exception *eh = __get_exception_header_from_obj (_M_exception_object); - return eh->exceptionType; -} - - -bool std::__exception_ptr::operator==(const exception_ptr& lhs, - const exception_ptr& rhs) throw() -{ - return lhs._M_exception_object == rhs._M_exception_object; -} - - -bool std::__exception_ptr::operator!=(const exception_ptr& lhs, - const exception_ptr& rhs) throw() -{ - return !(lhs == rhs); -} - - -std::exception_ptr -std::current_exception() throw() -{ - __cxa_eh_globals *globals = __cxa_get_globals (); - __cxa_exception *header = globals->caughtExceptions; - - if (!header) - return std::exception_ptr(); - - // Since foreign exceptions can't be counted, we can't return them. - if (!__is_gxx_exception_class (header->unwindHeader.exception_class)) - return std::exception_ptr(); - - return std::exception_ptr( - __get_object_from_ambiguous_exception (header)); -} - - -static void -__gxx_dependent_exception_cleanup (_Unwind_Reason_Code code, - _Unwind_Exception *exc) -{ - // This cleanup is set only for dependents. - __cxa_dependent_exception *dep = __get_dependent_exception_from_ue (exc); - __cxa_exception *header = - __get_exception_header_from_obj (dep->primaryException); - - // We only want to be called through _Unwind_DeleteException. - // _Unwind_DeleteException in the HP-UX IA64 libunwind library - // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT - // like the GCC _Unwind_DeleteException function does. - if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) - __terminate (header->terminateHandler); - - if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) - { - if (header->exceptionDestructor) - header->exceptionDestructor (header + 1); - - __cxa_free_exception (header + 1); - } -} - - -void -std::rethrow_exception(std::exception_ptr ep) -{ - void *obj = ep._M_get(); - __cxa_exception *eh = __get_exception_header_from_obj (obj); - - __cxa_dependent_exception *dep = __cxa_allocate_dependent_exception (); - dep->primaryException = obj; - __sync_add_and_fetch (&eh->referenceCount, 1); - - dep->unexpectedHandler = __unexpected_handler; - dep->terminateHandler = __terminate_handler; - __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(dep->unwindHeader.exception_class); - dep->unwindHeader.exception_cleanup = __gxx_dependent_exception_cleanup; - -#ifdef _GLIBCXX_SJLJ_EXCEPTIONS - _Unwind_SjLj_RaiseException (&dep->unwindHeader); -#else - _Unwind_RaiseException (&dep->unwindHeader); -#endif - - // Some sort of unwinding error. Note that terminate is a handler. - __cxa_begin_catch (&dep->unwindHeader); - std::terminate (); -} diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index 5887f26e9bb8..b405f8f7c641 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling routines for throwing. -// Copyright (C) 2001, 2003, 2008 Free Software Foundation, Inc. +// Copyright (C) 2001, 2003 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -36,23 +36,20 @@ using namespace __cxxabiv1; static void __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) { - // This cleanup is set only for primaries. __cxa_exception *header = __get_exception_header_from_ue (exc); - // We only want to be called through _Unwind_DeleteException. + // If we haven't been caught by a foreign handler, then this is + // some sort of unwind error. In that case just die immediately. // _Unwind_DeleteException in the HP-UX IA64 libunwind library - // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT + // returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT // like the GCC _Unwind_DeleteException function does. if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON) __terminate (header->terminateHandler); - if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) - { - if (header->exceptionDestructor) - header->exceptionDestructor (header + 1); + if (header->exceptionDestructor) + header->exceptionDestructor (header + 1); - __cxa_free_exception (header + 1); - } + __cxa_free_exception (header + 1); } @@ -60,14 +57,12 @@ extern "C" void __cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo, void (*dest) (void *)) { - // Definitely a primary. __cxa_exception *header = __get_exception_header_from_obj (obj); - header->referenceCount = 1; header->exceptionType = tinfo; header->exceptionDestructor = dest; header->unexpectedHandler = __unexpected_handler; header->terminateHandler = __terminate_handler; - __GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->unwindHeader.exception_class); + __GXX_INIT_EXCEPTION_CLASS(header->unwindHeader.exception_class); header->unwindHeader.exception_cleanup = __gxx_exception_cleanup; #ifdef _GLIBCXX_SJLJ_EXCEPTIONS diff --git a/libstdc++-v3/libsupc++/eh_type.cc b/libstdc++-v3/libsupc++/eh_type.cc index 034329767142..99627efdd976 100644 --- a/libstdc++-v3/libsupc++/eh_type.cc +++ b/libstdc++-v3/libsupc++/eh_type.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling routines for catching. -// Copyright (C) 2001, 2008 Free Software Foundation, Inc. +// Copyright (C) 2001 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -43,15 +43,7 @@ std::type_info *__cxa_current_exception_type () __cxa_eh_globals *globals = __cxa_get_globals (); __cxa_exception *header = globals->caughtExceptions; if (header) - { - if (__is_dependent_exception (header->unwindHeader.exception_class)) - { - __cxa_dependent_exception *de = - __get_dependent_exception_from_ue (&header->unwindHeader); - header = __get_exception_header_from_obj (de->primaryException); - } - return header->exceptionType; - } + return header->exceptionType; else return 0; } diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception index f1288211e985..a7e2db78dd19 100644 --- a/libstdc++-v3/libsupc++/exception +++ b/libstdc++-v3/libsupc++/exception @@ -1,7 +1,7 @@ // Exception Handling support header for -*- C++ -*- // Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, -// 2004, 2005, 2006, 2007, 2008 +// 2004, 2005, 2006, 2007 // Free Software Foundation // // This file is part of GCC. @@ -110,7 +110,6 @@ namespace std * result in a call of @c terminate() (15.5.1)." */ bool uncaught_exception() throw(); - } // namespace std _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) @@ -133,8 +132,4 @@ _GLIBCXX_END_NAMESPACE #pragma GCC visibility pop -#ifdef __GXX_EXPERIMENTAL_CXX0X__ -#include -#endif - #endif diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h index 77b0431c42f7..e69de29bb2d1 100644 --- a/libstdc++-v3/libsupc++/exception_ptr.h +++ b/libstdc++-v3/libsupc++/exception_ptr.h @@ -1,169 +0,0 @@ -// Exception Handling support header (exception_ptr class) for -*- C++ -*- - -// Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, -// 2004, 2005, 2006, 2007, 2008 -// Free Software Foundation -// -// This file is part of GCC. -// -// GCC is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2, or (at your option) -// any later version. -// -// GCC is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING. If not, write to -// the Free Software Foundation, 51 Franklin Street, Fifth Floor, -// Boston, MA 02110-1301, USA. - -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -/** @file exception_ptr.h - * This is an internal header file, included by other headers and the - * implementation. You should not attempt to use it directly. - */ - -#ifndef __EXCEPTION_PTR_H__ -#define __EXCEPTION_PTR_H__ - -#pragma GCC visibility push(default) - -#include - -extern "C++" { - -namespace std -{ - // Hide the free operators from other types - namespace __exception_ptr - { - /** - * @brief An opaque pointer to an arbitrary exception. - */ - class exception_ptr; - } - - using __exception_ptr::exception_ptr; - - /** Obtain an %exception_ptr to the currently handled exception. If there - * is none, or the currently handled exception is foreign, return the null - * value. - */ - exception_ptr current_exception() throw(); - - /// Throw the object pointed to by the %exception_ptr. - void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); - - /// Obtain an %exception_ptr pointing to a copy of the supplied object. - template - exception_ptr copy_exception(_Ex __ex) throw(); - - - namespace __exception_ptr - { - bool operator==(const exception_ptr&, - const exception_ptr&) throw(); - bool operator!=(const exception_ptr&, - const exception_ptr&) throw(); - - class exception_ptr - { - void* _M_exception_object; - - explicit exception_ptr(void* __e) throw(); - - void _M_addref() throw(); - void _M_release() throw(); - - void *_M_get() const throw(); - - void _M_safe_bool_dummy(); - - friend exception_ptr std::current_exception() throw(); - friend void std::rethrow_exception(exception_ptr); - - public: - exception_ptr() throw(); - - typedef void (exception_ptr::*__safe_bool)(); - - // For construction from nullptr or 0. - exception_ptr(__safe_bool) throw(); - - exception_ptr(const exception_ptr&) throw(); - -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - exception_ptr(exception_ptr&& __o) throw() - : _M_exception_object(__o._M_exception_object) - { - __o._M_exception_object = 0; - } -#endif - - exception_ptr& operator=(const exception_ptr&) throw(); - -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - exception_ptr& operator=(exception_ptr&& __o) throw() - { - exception_ptr(__o).swap(*this); - return *this; - } -#endif - - ~exception_ptr() throw(); - - void swap(exception_ptr&) throw(); - -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - void swap(exception_ptr &&__o) throw() - { - void *__tmp = _M_exception_object; - _M_exception_object = __o._M_exception_object; - __o._M_exception_object = __tmp; - } -#endif - - bool operator!() const throw(); - operator __safe_bool() const throw(); - - friend bool operator==(const exception_ptr&, - const exception_ptr&) throw(); - - const type_info *__cxa_exception_type() const throw(); - }; - - } // namespace __exception_ptr - - - template - exception_ptr copy_exception(_Ex __ex) throw() - { - try - { - throw __ex; - } - catch(...) - { - return current_exception (); - } - } - -} // namespace std - -} // extern "C++" - -#pragma GCC visibility pop - -#endif diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h index dc3fdc462d90..75874fc5da41 100644 --- a/libstdc++-v3/libsupc++/unwind-cxx.h +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling and frame unwind runtime interface routines. -// Copyright (C) 2001, 2008 Free Software Foundation, Inc. +// Copyright (C) 2001 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -45,15 +45,12 @@ namespace __cxxabiv1 { -// A primary C++ exception object consists of a header, which is a wrapper -// around an unwind object header with additional C++ specific information, +// A C++ exception object consists of a header, which is a wrapper around +// an unwind object header with additional C++ specific information, // followed by the exception object itself. struct __cxa_exception -{ - // Manage this header. - std::size_t referenceCount; - +{ // Manage the exception object itself. std::type_info *exceptionType; void (*exceptionDestructor)(void *); @@ -90,47 +87,6 @@ struct __cxa_exception _Unwind_Exception unwindHeader; }; -// A dependent C++ exception object consists of a wrapper around an unwind -// object header with additional C++ specific information, containing a pointer -// to a primary exception object. - -struct __cxa_dependent_exception -{ - // The primary exception this thing depends on. - void *primaryException; - - // The C++ standard has entertaining rules wrt calling set_terminate - // and set_unexpected in the middle of the exception cleanup process. - std::unexpected_handler unexpectedHandler; - std::terminate_handler terminateHandler; - - // The caught exception stack threads through here. - __cxa_exception *nextException; - - // How many nested handlers have caught this exception. A negated - // value is a signal that this object has been rethrown. - int handlerCount; - -#ifdef __ARM_EABI_UNWINDER__ - // Stack of exceptions in cleanups. - __cxa_exception* nextPropagatingException; - - // The nuber of active cleanup handlers for this exception. - int propagationCount; -#else - // Cache parsed handler data from the personality routine Phase 1 - // for Phase 2 and __cxa_call_unexpected. - int handlerSwitchValue; - const unsigned char *actionRecord; - const unsigned char *languageSpecificData; - _Unwind_Ptr catchTemp; - void *adjustedPtr; -#endif - - // The generic exception header. Must be last. - _Unwind_Exception unwindHeader; -}; - // Each thread in a C++ program has access to a __cxa_eh_globals object. struct __cxa_eh_globals { @@ -149,20 +105,12 @@ struct __cxa_eh_globals extern "C" __cxa_eh_globals *__cxa_get_globals () throw(); extern "C" __cxa_eh_globals *__cxa_get_globals_fast () throw(); -// Allocate memory for the primary exception plus the thrown object. +// Allocate memory for the exception plus the thown object. extern "C" void *__cxa_allocate_exception(std::size_t thrown_size) throw(); -// Free the space allocated for the primary exception. +// Free the space allocated for the exception. extern "C" void __cxa_free_exception(void *thrown_exception) throw(); -// Allocate memory for a dependent exception. -extern "C" __cxa_dependent_exception* -__cxa_allocate_dependent_exception() throw(); - -// Free the space allocated for the dependent exception. -extern "C" void -__cxa_free_dependent_exception(__cxa_dependent_exception *ex) throw(); - // Throw the exception. extern "C" void __cxa_throw (void *thrown_exception, std::type_info *tinfo, @@ -225,12 +173,6 @@ __get_exception_header_from_ue (_Unwind_Exception *exc) return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; } -static inline __cxa_dependent_exception * -__get_dependent_exception_from_ue (_Unwind_Exception *exc) -{ - return reinterpret_cast<__cxa_dependent_exception *>(exc + 1) - 1; -} - #ifdef __ARM_EABI_UNWINDER__ static inline bool __is_gxx_exception_class(_Unwind_Exception_Class c) @@ -243,19 +185,11 @@ __is_gxx_exception_class(_Unwind_Exception_Class c) && c[4] == 'C' && c[5] == '+' && c[6] == '+' - && (c[7] == '\0' || c[7] == '\x01'); -} - -// Only checks for primary or dependent, but not that it is a C++ exception at -// all. -static inline bool -__is_dependent_exception(_Unwind_Exception_Class c) -{ - return c[7] == '\x01'; + && c[7] == '\0'; } static inline void -__GXX_INIT_PRIMARY_EXCEPTION_CLASS(_Unwind_Exception_Class c) +__GXX_INIT_EXCEPTION_CLASS(_Unwind_Exception_Class c) { c[0] = 'G'; c[1] = 'N'; @@ -267,19 +201,6 @@ __GXX_INIT_PRIMARY_EXCEPTION_CLASS(_Unwind_Exception_Class c) c[7] = '\0'; } -static inline void -__GXX_INIT_DEPENDENT_EXCEPTION_CLASS(_Unwind_Exception_Class c) -{ - c[0] = 'G'; - c[1] = 'N'; - c[2] = 'U'; - c[3] = 'C'; - c[4] = 'C'; - c[5] = '+'; - c[6] = '+'; - c[7] = '\x01'; -} - static inline bool __is_gxx_forced_unwind_class(_Unwind_Exception_Class c) { @@ -312,8 +233,8 @@ __gxx_caught_object(_Unwind_Exception* eo) return (void*)eo->barrier_cache.bitpattern[0]; } #else // !__ARM_EABI_UNWINDER__ -// This is the primary exception class we report -- "GNUCC++\0". -const _Unwind_Exception_Class __gxx_primary_exception_class +// This is the exception class we report -- "GNUCC++\0". +const _Unwind_Exception_Class __gxx_exception_class = ((((((((_Unwind_Exception_Class) 'G' << 8 | (_Unwind_Exception_Class) 'N') << 8 | (_Unwind_Exception_Class) 'U') @@ -323,36 +244,13 @@ const _Unwind_Exception_Class __gxx_primary_exception_class << 8 | (_Unwind_Exception_Class) '+') << 8 | (_Unwind_Exception_Class) '\0'); -// This is the dependent (from std::rethrow_exception) exception class we report -// "GNUCC++\x01" -const _Unwind_Exception_Class __gxx_dependent_exception_class -= ((((((((_Unwind_Exception_Class) 'G' - << 8 | (_Unwind_Exception_Class) 'N') - << 8 | (_Unwind_Exception_Class) 'U') - << 8 | (_Unwind_Exception_Class) 'C') - << 8 | (_Unwind_Exception_Class) 'C') - << 8 | (_Unwind_Exception_Class) '+') - << 8 | (_Unwind_Exception_Class) '+') - << 8 | (_Unwind_Exception_Class) '\x01'); - static inline bool __is_gxx_exception_class(_Unwind_Exception_Class c) { - return c == __gxx_primary_exception_class - || c == __gxx_dependent_exception_class; + return c == __gxx_exception_class; } -// Only checks for primary or dependent, but not that it is a C++ exception at -// all. -static inline bool -__is_dependent_exception(_Unwind_Exception_Class c) -{ - return (c & 1); -} - -#define __GXX_INIT_PRIMARY_EXCEPTION_CLASS(c) c = __gxx_primary_exception_class -#define __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(c) \ - c = __gxx_dependent_exception_class +#define __GXX_INIT_EXCEPTION_CLASS(c) c = __gxx_exception_class // GNU C++ personality routine, Version 0. extern "C" _Unwind_Reason_Code __gxx_personality_v0 @@ -367,27 +265,11 @@ extern "C" _Unwind_Reason_Code __gxx_personality_sj0 static inline void* __gxx_caught_object(_Unwind_Exception* eo) { - // Bad as it looks, this actually works for dependent exceptions too. __cxa_exception* header = __get_exception_header_from_ue (eo); return header->adjustedPtr; } #endif // !__ARM_EABI_UNWINDER__ -static inline void* -__get_object_from_ue(_Unwind_Exception* eo) throw() -{ - return __is_dependent_exception (eo->exception_class) ? - __get_dependent_exception_from_ue (eo)->primaryException : - eo + 1; -} - -static inline void * -__get_object_from_ambiguous_exception(__cxa_exception *p_or_d) throw() -{ - return __get_object_from_ue (&p_or_d->unwindHeader); -} - - } /* namespace __cxxabiv1 */ #pragma GCC visibility pop diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc index d4a63e4b0014..e69de29bb2d1 100644 --- a/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc +++ b/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc @@ -1,90 +0,0 @@ -// { dg-options "-std=gnu++0x" } -// 2008-05-25 Sebastian Redl - -// Copyright (C) 2008 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. - -// current_exception() under various conditions. - -#include -#include - -void test01() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - exception_ptr ep = current_exception(); - VERIFY( !ep ); -} - -void test02() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - try { - throw 0; - } catch(...) { - exception_ptr ep = current_exception(); - VERIFY( ep ); - } -} - -void test03() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - try { - throw exception(); - } catch(std::exception&) { - exception_ptr ep = current_exception(); - VERIFY( ep ); - } -} - -void test04() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - try { - throw 0; - } catch(...) { - exception_ptr ep1 = current_exception(); - try { - throw 0; - } catch(...) { - exception_ptr ep2 = current_exception(); - VERIFY( ep1 != ep2 ); - } - exception_ptr ep3 = current_exception(); - // Not guaranteed by standard, but by this implementation. - VERIFY( ep1 == ep3 ); - } -} - -int main() -{ - test01(); - test02(); - test03(); - test04(); - return 0; -} diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/lifespan.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/lifespan.cc index 1107a2ece602..e69de29bb2d1 100644 --- a/libstdc++-v3/testsuite/18_support/exception_ptr/lifespan.cc +++ b/libstdc++-v3/testsuite/18_support/exception_ptr/lifespan.cc @@ -1,188 +0,0 @@ -// { dg-options "-std=gnu++0x" } -// 2008-05-25 Sebastian Redl - -// Copyright (C) 2008 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. - -// Tests the life span of the exception object. - -#include -#include - -bool may_destruct = false; - -class destructing -{ - mutable bool copied; - -public: - destructing() : copied(false) { } - destructing(const destructing &o) : copied(false) { o.copied = true; } - ~destructing() { VERIFY( copied || may_destruct ); } -}; - -void test01() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - may_destruct = false; - - // Test the destructing class. - { - destructing *d = new destructing; - destructing d2(*d); - delete d; - may_destruct = true; - } - may_destruct = false; -} - -void test02() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - may_destruct = false; - - try { - throw destructing(); - } catch(...) { - may_destruct = true; - } - may_destruct = false; -} - -void test03() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - may_destruct = false; - - try { - throw destructing(); - } catch(...) { - { - exception_ptr ep = current_exception(); - } - may_destruct = true; - } - may_destruct = false; -} - -void test04() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - may_destruct = false; - - { - exception_ptr ep; - try { - throw destructing(); - } catch(...) { - ep = current_exception(); - } - may_destruct = true; - } - may_destruct = false; -} - -void test05_helper() -{ - using namespace std; - try { - throw destructing(); - } catch(...) { - exception_ptr ep = current_exception(); - rethrow_exception(ep); - } -} - -void test05() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - may_destruct = false; - - try { - test05_helper(); - } catch(...) { - may_destruct = true; - } - may_destruct = false; -} - -void test06_helper() -{ - using namespace std; - try { - throw destructing(); - } catch(...) { - exception_ptr ep = current_exception(); - throw; - } -} - -void test06() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - may_destruct = false; - - try { - test06_helper(); - } catch(...) { - may_destruct = true; - } - may_destruct = false; -} - -std::exception_ptr gep; - -void test99() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - may_destruct = false; - - try { - throw destructing(); - } catch(...) { - gep = current_exception(); - } -} - -int main() -{ - test01(); - test02(); - test03(); - test04(); - test05(); - test06(); - - test99(); - may_destruct = true; - return 0; -} diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/rethrow_exception.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/rethrow_exception.cc index 96d38d5eba3e..e69de29bb2d1 100644 --- a/libstdc++-v3/testsuite/18_support/exception_ptr/rethrow_exception.cc +++ b/libstdc++-v3/testsuite/18_support/exception_ptr/rethrow_exception.cc @@ -1,113 +0,0 @@ -// { dg-options "-std=gnu++0x" } -// 2008-05-25 Sebastian Redl - -// Copyright (C) 2008 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. - -// rethrow_exception() and preservation of data - -#include -#include -#include -#include -#include - -void test01() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - try { - rethrow_exception(copy_exception(0)); - } catch(...) { - } -} - -void test02() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - try { - rethrow_exception(copy_exception(runtime_error("test"))); - } catch(exception &e) { - VERIFY( typeid(e) == typeid(runtime_error) ); - VERIFY( strcmp(e.what(), "test") == 0 ); - } -} - -void test03() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - exception_ptr ep; - try { - throw 0; - } catch(...) { - ep = current_exception(); - } - try { - rethrow_exception(ep); - } catch(...) { - } -} - -void test04() -{ - bool test __attribute__((unused)) = true; - using namespace std; - - // Weave the exceptions in an attempt to confuse the machinery. - try { - throw 0; - } catch(...) { - exception_ptr ep1 = current_exception(); - try { - throw 1; - } catch(...) { - exception_ptr ep2 = current_exception(); - try { - rethrow_exception(ep1); - } catch(...) { - try { - rethrow_exception(ep2); - } catch(...) { - try { - rethrow_exception(ep1); - } catch(...) { - } - try { - rethrow_exception(ep2); - } catch(...) { - } - } - } - } - } -} - -int main() -{ - test01(); - test02(); - test03(); - test04(); - - return 0; -}