From 991d600f0110059bb396428d164bc62840771ba6 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Wed, 15 Mar 2017 11:39:42 -0700 Subject: [PATCH] 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 {