From cf05dc079b06f5f942b2bf4f74ecbdaf41fd815a Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Mon, 13 Mar 2017 15:07:09 -0700 Subject: [PATCH 1/3] Removing non-intrusive exception_ptr support. --- build/Jamfile.v2 | 14 - .../detail/clone_current_exception.hpp | 59 ---- .../boost/exception/detail/exception_ptr.hpp | 215 +++++------- include/boost/exception/exception_data.hpp | 81 +++++ src/clone_current_exception_non_intrusive.cpp | 320 ------------------ test/Jamfile.v2 | 1 - test/cloning_test.cpp | 21 -- test/unknown_exception_test.cpp | 19 -- 8 files changed, 173 insertions(+), 557 deletions(-) delete mode 100644 build/Jamfile.v2 delete mode 100644 include/boost/exception/detail/clone_current_exception.hpp create mode 100644 include/boost/exception/exception_data.hpp delete mode 100644 src/clone_current_exception_non_intrusive.cpp 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/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/exception_data.hpp b/include/boost/exception/exception_data.hpp new file mode 100644 index 0000000..cf2ded1 --- /dev/null +++ b/include/boost/exception/exception_data.hpp @@ -0,0 +1,81 @@ +//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) + +#ifndef UUID_D63C9FFE03C611E7B6F710AB63EDCBF1 +#define UUID_D63C9FFE03C611E7B6F710AB63EDCBF1 + +namespace +boost + { + class + exception_datum + { + exception_datum( exception_datum const & ); + exception_datum & operator=( exception_datum const & ); + std::type_info ti_; + shared_ptr v_; + public: + explicit + template + exception_datum( T const & v ): + ti_(typeid(T)), + v_(make_shared(v)) + { + } + template + T * + cast() + { + if( typeid(T)==ti_ ) + return static_cast(v_.get()); + else + return 0; + } + }; + class + exception_data + { + std::map data_; + protected: + exception_data() + { + } + ~exception_data() + { + } + public: + template + exception_data & + set( char const * tag, T const & value ) + { + data_[tag]=exception_datum(value); + return *this; + } + template + T const * + get( char const * tag ) const + { + auto it=data_.find(tag); + if( it!=data_.end() ) + return it->cast(); + else + return 0; + } + }; + } + +catch( +exception_data & d ) + { + d["file_name"].set("foo.txt"); + d["file_name"].get(); + + d.set("file_name","foo.txt"); + throw; + } + +throw_exception(foo_error(),make_pair("errno",errno),pair("width",width)); + +#endif 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/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); From 10550b69d4239cd98ce35cffa5f1c26a56e0df7e Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Mon, 13 Mar 2017 16:08:34 -0700 Subject: [PATCH 2/3] Deleting accidentally committed file. --- include/boost/exception/exception_data.hpp | 81 ---------------------- 1 file changed, 81 deletions(-) delete mode 100644 include/boost/exception/exception_data.hpp diff --git a/include/boost/exception/exception_data.hpp b/include/boost/exception/exception_data.hpp deleted file mode 100644 index cf2ded1..0000000 --- a/include/boost/exception/exception_data.hpp +++ /dev/null @@ -1,81 +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) - -#ifndef UUID_D63C9FFE03C611E7B6F710AB63EDCBF1 -#define UUID_D63C9FFE03C611E7B6F710AB63EDCBF1 - -namespace -boost - { - class - exception_datum - { - exception_datum( exception_datum const & ); - exception_datum & operator=( exception_datum const & ); - std::type_info ti_; - shared_ptr v_; - public: - explicit - template - exception_datum( T const & v ): - ti_(typeid(T)), - v_(make_shared(v)) - { - } - template - T * - cast() - { - if( typeid(T)==ti_ ) - return static_cast(v_.get()); - else - return 0; - } - }; - class - exception_data - { - std::map data_; - protected: - exception_data() - { - } - ~exception_data() - { - } - public: - template - exception_data & - set( char const * tag, T const & value ) - { - data_[tag]=exception_datum(value); - return *this; - } - template - T const * - get( char const * tag ) const - { - auto it=data_.find(tag); - if( it!=data_.end() ) - return it->cast(); - else - return 0; - } - }; - } - -catch( -exception_data & d ) - { - d["file_name"].set("foo.txt"); - d["file_name"].get(); - - d.set("file_name","foo.txt"); - throw; - } - -throw_exception(foo_error(),make_pair("errno",errno),pair("width",width)); - -#endif From 991d600f0110059bb396428d164bc62840771ba6 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Wed, 15 Mar 2017 11:39:42 -0700 Subject: [PATCH 3/3] Fixing bug in exception_ptr cloning of error_info objects. --- .../exception/detail/error_info_impl.hpp | 8 +++-- include/boost/exception/info.hpp | 6 +++- test/exception_ptr_test.cpp | 33 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/include/boost/exception/detail/error_info_impl.hpp b/include/boost/exception/detail/error_info_impl.hpp index 1928d4a..9f3e21e 100644 --- a/include/boost/exception/detail/error_info_impl.hpp +++ b/include/boost/exception/detail/error_info_impl.hpp @@ -29,8 +29,7 @@ boost public: virtual std::string name_value_string() const = 0; - - protected: + virtual error_info_base * clone() const = 0; virtual ~error_info_base() throw() @@ -44,6 +43,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/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/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 {