diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 deleted file mode 100644 index fb47659..0000000 --- a/build/Jamfile.v2 +++ /dev/null @@ -1,14 +0,0 @@ -# Boost Exception Library build Jamfile -# -# Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. -# -# Distributed under the Boost Software License, Version 1.0. (See accompanying -# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -project boost/exception - : source-location ../src - : requirements static - ; - -lib boost_exception : clone_current_exception_non_intrusive.cpp ; -boost-install boost_exception ; diff --git a/include/boost/exception/detail/clone_current_exception.hpp b/include/boost/exception/detail/clone_current_exception.hpp deleted file mode 100644 index 3d86deb..0000000 --- a/include/boost/exception/detail/clone_current_exception.hpp +++ /dev/null @@ -1,59 +0,0 @@ -//Copyright (c) 2006-2013 Emil Dotchevski and Reverge Studios, Inc. - -//Distributed under the Boost Software License, Version 1.0. (See accompanying -//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef UUID_81522C0EB56511DFAB613DB0DFD72085 -#define UUID_81522C0EB56511DFAB613DB0DFD72085 - -#include - -#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) -#pragma GCC system_header -#endif -#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) -#pragma warning(push,1) -#endif - -#ifdef BOOST_NO_EXCEPTIONS -# error This header requires exception handling to be enabled. -#endif - -namespace -boost - { - namespace - exception_detail - { - class clone_base; - -#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR - int clone_current_exception_non_intrusive( clone_base const * & cloned ); -#endif - - namespace - clone_current_exception_result - { - int const success=0; - int const bad_alloc=1; - int const bad_exception=2; - int const not_supported=3; - } - - inline - int - clone_current_exception( clone_base const * & cloned ) - { -#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR - return clone_current_exception_non_intrusive(cloned); -#else - return clone_current_exception_result::not_supported; -#endif - } - } - } - -#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) -#pragma warning(pop) -#endif -#endif diff --git a/include/boost/exception/detail/error_info_impl.hpp b/include/boost/exception/detail/error_info_impl.hpp index a3063b2..2c85d3c 100644 --- a/include/boost/exception/detail/error_info_impl.hpp +++ b/include/boost/exception/detail/error_info_impl.hpp @@ -32,8 +32,7 @@ boost public: virtual std::string name_value_string() const = 0; - - protected: + virtual error_info_base * clone() const = 0; virtual ~error_info_base() throw() @@ -47,6 +46,11 @@ boost error_info: public exception_detail::error_info_base { + error_info_base * + clone() const + { + return new error_info(*this); + } public: typedef T value_type; error_info( value_type const & v ): diff --git a/include/boost/exception/detail/exception_ptr.hpp b/include/boost/exception/detail/exception_ptr.hpp index 5aa4773..24c4fba 100644 --- a/include/boost/exception/detail/exception_ptr.hpp +++ b/include/boost/exception/detail/exception_ptr.hpp @@ -14,7 +14,6 @@ #include #include #include -#include #ifndef BOOST_NO_RTTI #include #endif @@ -303,131 +302,101 @@ boost exception_ptr current_exception_impl() { - exception_detail::clone_base const * e=0; - switch( - exception_detail::clone_current_exception(e) ) + try { - case exception_detail::clone_current_exception_result:: - success: - { - BOOST_ASSERT(e!=0); - return exception_ptr(shared_ptr(e)); - } - case exception_detail::clone_current_exception_result:: - bad_alloc: - { - BOOST_ASSERT(!e); - return exception_detail::exception_ptr_static_exception_object::e; - } - case exception_detail::clone_current_exception_result:: - bad_exception: - { - BOOST_ASSERT(!e); - return exception_detail::exception_ptr_static_exception_object::e; - } - default: - BOOST_ASSERT(0); - case exception_detail::clone_current_exception_result:: - not_supported: - { - BOOST_ASSERT(!e); - try - { - throw; - } - catch( - exception_detail::clone_base & e ) - { - return exception_ptr(shared_ptr(e.clone())); - } - catch( - std::domain_error & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::invalid_argument & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::length_error & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::out_of_range & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::logic_error & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::range_error & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::overflow_error & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::underflow_error & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::ios_base::failure & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::runtime_error & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::bad_alloc & e ) - { - return exception_detail::current_exception_std_exception(e); - } + throw; + } + catch( + exception_detail::clone_base & e ) + { + return exception_ptr(shared_ptr(e.clone())); + } + catch( + std::domain_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::invalid_argument & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::length_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::out_of_range & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::logic_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::range_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::overflow_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::underflow_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::ios_base::failure & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::runtime_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::bad_alloc & e ) + { + return exception_detail::current_exception_std_exception(e); + } #ifndef BOOST_NO_TYPEID - catch( - std::bad_cast & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::bad_typeid & e ) - { - return exception_detail::current_exception_std_exception(e); - } + catch( + std::bad_cast & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::bad_typeid & e ) + { + return exception_detail::current_exception_std_exception(e); + } #endif - catch( - std::bad_exception & e ) - { - return exception_detail::current_exception_std_exception(e); - } - catch( - std::exception & e ) - { - return exception_detail::current_exception_unknown_std_exception(e); - } - catch( - boost::exception & e ) - { - return exception_detail::current_exception_unknown_boost_exception(e); - } - catch( - ... ) - { - return exception_detail::current_exception_unknown_exception(); - } - } + catch( + std::bad_exception & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::exception & e ) + { + return exception_detail::current_exception_unknown_std_exception(e); + } + catch( + boost::exception & e ) + { + return exception_detail::current_exception_unknown_boost_exception(e); + } + catch( + ... ) + { + return exception_detail::current_exception_unknown_exception(); } } } diff --git a/include/boost/exception/info.hpp b/include/boost/exception/info.hpp index c99578a..f7ac50e 100644 --- a/include/boost/exception/info.hpp +++ b/include/boost/exception/info.hpp @@ -142,7 +142,11 @@ boost refcount_ptr p; error_info_container_impl * c=new error_info_container_impl; p.adopt(c); - c->info_ = info_; + for( error_info_map::const_iterator i=info_.begin(),e=info_.end(); i!=e; ++i ) + { + shared_ptr cp(i->second->clone()); + c->info_.insert(std::make_pair(i->first,cp)); + } return p; } }; diff --git a/src/clone_current_exception_non_intrusive.cpp b/src/clone_current_exception_non_intrusive.cpp deleted file mode 100644 index 1710cd7..0000000 --- a/src/clone_current_exception_non_intrusive.cpp +++ /dev/null @@ -1,320 +0,0 @@ -//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. - -//Distributed under the Boost Software License, Version 1.0. (See accompanying -//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -//This MSVC-specific cpp file implements non-intrusive cloning of exception objects. -//Based on an exception_ptr implementation by Anthony Williams. - -#ifdef BOOST_NO_EXCEPTIONS -#error This file requires exception handling to be enabled. -#endif - -#include - -#if defined(BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR) && defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64) - -//Non-intrusive cloning support implemented below, only for MSVC versions mentioned above. -//Thanks Anthony Williams! - -#include -#include -#ifndef BOOST_NO_RTTI -#include -#endif -#include -#include - -namespace - { - unsigned const exception_maximum_parameters=15; - unsigned const exception_noncontinuable=1; - -#if _MSC_VER==1310 - int const exception_info_offset=0x74; -#elif (_MSC_VER==1400 || _MSC_VER==1500) - int const exception_info_offset=0x80; -#else - int const exception_info_offset=-1; -#endif - - struct - exception_record - { - unsigned long ExceptionCode; - unsigned long ExceptionFlags; - exception_record * ExceptionRecord; - void * ExceptionAddress; - unsigned long NumberParameters; - ULONG_PTR ExceptionInformation[exception_maximum_parameters]; - }; - - struct - exception_pointers - { - exception_record * ExceptionRecord; - void * ContextRecord; - }; - - unsigned const cpp_exception_code=0xE06D7363; - unsigned const cpp_exception_magic_flag=0x19930520; - unsigned const cpp_exception_parameter_count=3; - - struct - dummy_exception_type - { - }; - - typedef int(dummy_exception_type::*normal_copy_constructor_ptr)(void * src); - typedef int(dummy_exception_type::*copy_constructor_with_virtual_base_ptr)(void * src,void * dst); - typedef void (dummy_exception_type::*destructor_ptr)(); - - union - cpp_copy_constructor - { - normal_copy_constructor_ptr normal_copy_constructor; - copy_constructor_with_virtual_base_ptr copy_constructor_with_virtual_base; - }; - - enum - cpp_type_flags - { - class_is_simple_type=1, - class_has_virtual_base=4 - }; - - struct - cpp_type_info - { - unsigned flags; -#ifndef BOOST_NO_RTTI - void const * type_info; -#else - std::type_info * type_info; -#endif - int this_offset; - int vbase_descr; - int vbase_offset; - unsigned long size; - cpp_copy_constructor copy_constructor; - }; - - struct - cpp_type_info_table - { - unsigned count; - const cpp_type_info * info[1]; - }; - - struct - cpp_exception_type - { - unsigned flags; - destructor_ptr destructor; - void(*custom_handler)(); - cpp_type_info_table const * type_info_table; - }; - - struct - exception_object_deleter - { - cpp_exception_type const & et_; - - exception_object_deleter( cpp_exception_type const & et ): - et_(et) - { - } - - void - operator()( void * obj ) - { - BOOST_ASSERT(obj!=0); - dummy_exception_type * dummy_exception_ptr=reinterpret_cast(obj); - (dummy_exception_ptr->*(et_.destructor))(); - free(obj); - } - }; - - cpp_type_info const & - get_cpp_type_info( cpp_exception_type const & et ) - { - cpp_type_info const * ti = et.type_info_table->info[0]; - BOOST_ASSERT(ti!=0); - return *ti; - } - - void - copy_msvc_exception( void * dst, void * src, cpp_type_info const & ti ) - { - if( !(ti.flags & class_is_simple_type) && ti.copy_constructor.normal_copy_constructor ) - { - dummy_exception_type * dummy_exception_ptr = reinterpret_cast(dst); - if( ti.flags & class_has_virtual_base ) - (dummy_exception_ptr->*(ti.copy_constructor.copy_constructor_with_virtual_base))(src,dst); - else - (dummy_exception_ptr->*(ti.copy_constructor.normal_copy_constructor))(src); - } - else - memmove(dst,src,ti.size); - } - - boost::shared_ptr - clone_msvc_exception( void * src, cpp_exception_type const & et ) - { - assert(src!=0); - cpp_type_info const & ti=get_cpp_type_info(et); - if( void * dst = malloc(ti.size) ) - { - try - { - copy_msvc_exception(dst,src,ti); - } - catch( - ... ) - { - free(dst); - throw; - } - return boost::shared_ptr(dst,exception_object_deleter(et)); - } - else - throw std::bad_alloc(); - } - - class - cloned_exception: - public boost::exception_detail::clone_base - { - cloned_exception( cloned_exception const & ); - cloned_exception & operator=( cloned_exception const & ); - - cpp_exception_type const & et_; - boost::shared_ptr exc_; - - public: - - cloned_exception( void * exc, cpp_exception_type const & et ): - et_(et), - exc_(clone_msvc_exception(exc,et_)) - { - } - - ~cloned_exception() throw() - { - } - - boost::exception_detail::clone_base const * - clone() const - { - return new cloned_exception(exc_.get(),et_); - } - - void - rethrow() const - { - cpp_type_info const & ti=get_cpp_type_info(et_); - void * dst = _alloca(ti.size); - copy_msvc_exception(dst,exc_.get(),ti); - ULONG_PTR args[cpp_exception_parameter_count]; - args[0]=cpp_exception_magic_flag; - args[1]=reinterpret_cast(dst); - args[2]=reinterpret_cast(&et_); - RaiseException(cpp_exception_code,EXCEPTION_NONCONTINUABLE,cpp_exception_parameter_count,args); - } - }; - - bool - is_cpp_exception( EXCEPTION_RECORD const * record ) - { - return record && - (record->ExceptionCode==cpp_exception_code) && - (record->NumberParameters==cpp_exception_parameter_count) && - (record->ExceptionInformation[0]==cpp_exception_magic_flag); - } - - unsigned long - exception_cloning_filter( int & result, boost::exception_detail::clone_base const * & ptr, void * info_ ) - { - BOOST_ASSERT(exception_info_offset>=0); - BOOST_ASSERT(info_!=0); - EXCEPTION_POINTERS * info=reinterpret_cast(info_); - EXCEPTION_RECORD * record=info->ExceptionRecord; - if( is_cpp_exception(record) ) - { - if( !record->ExceptionInformation[2] ) - record = *reinterpret_cast(reinterpret_cast(_errno())+exception_info_offset); - if( is_cpp_exception(record) && record->ExceptionInformation[2] ) - try - { - ptr = new cloned_exception( - reinterpret_cast(record->ExceptionInformation[1]), - *reinterpret_cast(record->ExceptionInformation[2])); - result = boost::exception_detail::clone_current_exception_result::success; - } - catch( - std::bad_alloc & ) - { - result = boost::exception_detail::clone_current_exception_result::bad_alloc; - } - catch( - ... ) - { - result = boost::exception_detail::clone_current_exception_result::bad_exception; - } - } - return EXCEPTION_EXECUTE_HANDLER; - } - } - -namespace -boost - { - namespace - exception_detail - { - int - clone_current_exception_non_intrusive( clone_base const * & cloned ) - { - BOOST_ASSERT(!cloned); - int result = clone_current_exception_result::not_supported; - if( exception_info_offset>=0 ) - { - clone_base const * ptr=0; - __try - { - throw; - } - __except(exception_cloning_filter(result,ptr,GetExceptionInformation())) - { - } - if( result==clone_current_exception_result::success ) - cloned=ptr; - } - BOOST_ASSERT(result!=clone_current_exception_result::success || cloned); - return result; - } - } - } - -#else - -//On all other compilers, return clone_current_exception_result::not_supported. -//On such platforms, only the intrusive enable_current_exception() cloning will work. - -#include - -namespace -boost - { - namespace - exception_detail - { - int - clone_current_exception_non_intrusive( clone_base const * & ) - { - return clone_current_exception_result::not_supported; - } - } - } - -#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 53d277f..97bc3ec 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -44,7 +44,6 @@ run refcount_ptr_test.cpp ; run current_exception_cast_test.cpp ; run no_exceptions_test.cpp : : : off ; run errinfos_test.cpp ; -run exception_ptr_test.cpp/BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR ../../thread/src/tss_null.cpp /boost/exception /boost//thread : : : multi : non_intrusive_exception_ptr_test ; run exception_ptr_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : multi ; run N3757_test.cpp ; diff --git a/test/cloning_test.cpp b/test/cloning_test.cpp index c5a4ae9..70010aa 100644 --- a/test/cloning_test.cpp +++ b/test/cloning_test.cpp @@ -395,11 +395,6 @@ main() BOOST_TEST(false); } catch( - derives_std_exception & ) - { - //Yay! Non-intrusive cloning supported! - } - catch( boost::unknown_exception & e ) { #ifndef BOOST_NO_RTTI @@ -449,14 +444,6 @@ main() BOOST_TEST(false); } catch( - derives_std_boost_exception & x ) - { - //Yay! Non-intrusive cloning supported! - BOOST_TEST(boost::get_error_info(x)); - if( int const * p=boost::get_error_info(x) ) - BOOST_TEST(*p==42); - } - catch( boost::unknown_exception & x ) { BOOST_TEST(boost::get_error_info(x)); @@ -518,14 +505,6 @@ main() BOOST_TEST(false); } catch( - derives_boost_exception & x ) - { - //Yay! Non-intrusive cloning supported! - BOOST_TEST(boost::get_error_info(x)); - if( int const * p=boost::get_error_info(x) ) - BOOST_TEST(*p==42); - } - catch( boost::unknown_exception & x ) { BOOST_TEST(boost::get_error_info(x)); diff --git a/test/exception_ptr_test.cpp b/test/exception_ptr_test.cpp index 193fabc..4c626c5 100644 --- a/test/exception_ptr_test.cpp +++ b/test/exception_ptr_test.cpp @@ -121,9 +121,42 @@ check( boost::shared_ptr const & t ) } } +void +test_deep_copy() + { + int const * p1=0; + boost::exception_ptr p; + try + { + BOOST_THROW_EXCEPTION(exc() << answer(42)); + BOOST_ERROR("BOOST_THROW_EXCEPTION didn't throw"); + } + catch( + exc & e ) + { + p1=boost::get_error_info(e); + p=boost::current_exception(); + } + BOOST_TEST(p1!=0); + BOOST_TEST(p); + try + { + boost::rethrow_exception(p); + BOOST_ERROR("rethrow_exception didn't throw"); + } + catch( + exc & e ) + { + int const * p2=boost::get_error_info(e); + BOOST_TEST(p2!=0 && *p2==42); + BOOST_TEST(p2!=p1); + } + } + int main() { + test_deep_copy(); BOOST_TEST(++exc_count==1); try { diff --git a/test/unknown_exception_test.cpp b/test/unknown_exception_test.cpp index bf474ba..4918b44 100644 --- a/test/unknown_exception_test.cpp +++ b/test/unknown_exception_test.cpp @@ -62,15 +62,6 @@ main() BOOST_TEST(false); } catch( - boost::exception & x ) - { - //Yay! Non-intrusive cloning supported! - if( int const * d=boost::get_error_info(x) ) - BOOST_TEST( 42==*d ); - else - BOOST_TEST(false); - } - catch( ... ) { BOOST_TEST(false); @@ -110,11 +101,6 @@ main() { } catch( - std::exception & ) - { - //Yay! Non-intrusive cloning supported! - } - catch( ... ) { BOOST_TEST(false); @@ -128,11 +114,6 @@ main() { } catch( - std::exception & ) - { - //Yay! Non-intrusive cloning supported! - } - catch( ... ) { BOOST_TEST(false);