diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..507b9eb --- /dev/null +++ b/.travis.yml @@ -0,0 +1,99 @@ +# Copyright 2017 Emil Dotchevski +# Copyright 2016 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) + +language: cpp + +sudo: false + +python: "2.7" + +os: + - linux + - osx + +branches: + only: + - master + - develop + +env: + matrix: + - BOGUS_JOB=true + +addons: + apt: + packages: + - g++-4.7 + - g++-4.8 + - g++-4.9 + - g++-5 + - g++-6 + - clang-3.6 + - clang-3.7 + - clang-3.8 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise + - llvm-toolchain-precise-3.6 + - llvm-toolchain-precise-3.7 + - llvm-toolchain-precise-3.8 + +matrix: + + exclude: + - env: BOGUS_JOB=true + + include: + - os: linux + env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++0x + + - os: linux + env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++0x + + - os: linux + env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++0x + + - os: linux + env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++0x + + - os: linux + env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++0x + + - os: linux + env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++0x + + - os: linux + env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++0x + + - os: linux + env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++0x + + - os: linux + env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++0x + + - os: osx + env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++0x + +install: + - cd .. + - git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + - cd boost-root + - git submodule update --init tools/build + - git submodule update --init tools/inspect + - git submodule update --init libs/config + - git submodule update --init tools/boostdep + - cp -r $TRAVIS_BUILD_DIR/* libs/exception + - python tools/boostdep/depinst/depinst.py exception + - ./bootstrap.sh + - ./b2 headers + +script: + - |- + echo "using $TOOLSET : : $COMPILER : -std=$CXXSTD ;" > ~/user-config.jam + - ./b2 libs/exception/test toolset=$TOOLSET + +notifications: + email: + on_success: always diff --git a/include/boost/exception/N3757.hpp b/include/boost/exception/N3757.hpp index 23b0606..1bc298d 100644 --- a/include/boost/exception/N3757.hpp +++ b/include/boost/exception/N3757.hpp @@ -5,6 +5,10 @@ #ifndef UUID_9011016A11A711E3B46CD9FA6088709B #define UUID_9011016A11A711E3B46CD9FA6088709B + +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,9 +16,6 @@ #pragma warning(push,1) #endif -#include -#include - namespace boost { diff --git a/include/boost/exception/all.hpp b/include/boost/exception/all.hpp index 32eb150..58b02d0 100644 --- a/include/boost/exception/all.hpp +++ b/include/boost/exception/all.hpp @@ -5,13 +5,8 @@ #ifndef UUID_316FDA946C0D11DEA9CBAE5255D89593 #define UUID_316FDA946C0D11DEA9CBAE5255D89593 -#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 +#include #include #include #include @@ -29,8 +24,4 @@ #include #include #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 ecd086d..6c48d61 100644 --- a/include/boost/exception/detail/error_info_impl.hpp +++ b/include/boost/exception/detail/error_info_impl.hpp @@ -5,6 +5,14 @@ #ifndef UUID_CE6983AC753411DDA764247956D89593 #define UUID_CE6983AC753411DDA764247956D89593 + +#include +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#include +#endif +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,10 +20,6 @@ #pragma warning(push,1) #endif -#include -#include -#include - namespace boost { @@ -28,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() @@ -43,39 +46,53 @@ 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 & value ); + error_info( value_type const & v ): + v_(v) + { + } +#if (__GNUC__*100+__GNUC_MINOR__!=406) //workaround for g++ bug #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - error_info( error_info const & ); - error_info( value_type && value ) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(value_type(std::move(value)))); - error_info( error_info && x ) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(value_type(std::move(x.value_)))); + error_info( error_info const & x ): + v_(x.v_) + { + } + error_info( T && v ) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible::value): + v_(std::move(v)) + { + } + error_info( error_info && x ) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible::value): + v_(std::move(x.v_)) + { + } #endif - ~error_info() throw(); - +#endif + ~error_info() throw() + { + } value_type const & value() const { - return value_; + return v_; } - value_type & value() { - return value_; + return v_; } - private: error_info & operator=( error_info const & ); #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES error_info & operator=( error_info && x ); #endif - std::string name_value_string() const; - - value_type value_; + value_type v_; }; } diff --git a/include/boost/exception/detail/exception_ptr.hpp b/include/boost/exception/detail/exception_ptr.hpp index cac64e6..8e19f0d 100644 --- a/include/boost/exception/detail/exception_ptr.hpp +++ b/include/boost/exception/detail/exception_ptr.hpp @@ -5,12 +5,6 @@ #ifndef UUID_618474C2DE1511DEB74A388C56D89593 #define UUID_618474C2DE1511DEB74A388C56D89593 -#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 #include #ifdef BOOST_NO_EXCEPTIONS @@ -19,8 +13,8 @@ #include #include #include -#include #include +#include #ifndef BOOST_NO_RTTI #include #endif @@ -30,6 +24,13 @@ #include #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 + namespace boost { @@ -394,7 +395,7 @@ boost { return exception_detail::current_exception_std_exception(e); } -#ifndef BOOST_NO_TYPEID + #ifndef BOOST_NO_TYPEID catch( std::bad_cast & e ) { @@ -405,7 +406,7 @@ boost { return exception_detail::current_exception_std_exception(e); } -#endif + #endif catch( std::bad_exception & e ) { diff --git a/include/boost/exception/detail/is_output_streamable.hpp b/include/boost/exception/detail/is_output_streamable.hpp index 847f348..10e5c51 100644 --- a/include/boost/exception/detail/is_output_streamable.hpp +++ b/include/boost/exception/detail/is_output_streamable.hpp @@ -5,6 +5,9 @@ #ifndef UUID_898984B4076411DD973EDFA055D89593 #define UUID_898984B4076411DD973EDFA055D89593 + +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,8 +15,6 @@ #pragma warning(push,1) #endif -#include - namespace boost { diff --git a/include/boost/exception/detail/object_hex_dump.hpp b/include/boost/exception/detail/object_hex_dump.hpp index 53c8bf6..267bf0b 100644 --- a/include/boost/exception/detail/object_hex_dump.hpp +++ b/include/boost/exception/detail/object_hex_dump.hpp @@ -5,12 +5,6 @@ #ifndef UUID_6F463AC838DF11DDA3E6909F56D89593 #define UUID_6F463AC838DF11DDA3E6909F56D89593 -#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 #include #include @@ -19,6 +13,13 @@ #include #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 + namespace boost { diff --git a/include/boost/exception/detail/type_info.hpp b/include/boost/exception/detail/type_info.hpp index b8c7d48..739ac57 100644 --- a/include/boost/exception/detail/type_info.hpp +++ b/include/boost/exception/detail/type_info.hpp @@ -5,6 +5,13 @@ #ifndef UUID_C3E1741C754311DDB2834CCA55D89593 #define UUID_C3E1741C754311DDB2834CCA55D89593 + +#include +#include +#include +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,12 +19,6 @@ #pragma warning(push,1) #endif -#include -#include -#include -#include -#include - namespace boost { diff --git a/include/boost/exception/diagnostic_information.hpp b/include/boost/exception/diagnostic_information.hpp index 305e8ed..48f06a0 100644 --- a/include/boost/exception/diagnostic_information.hpp +++ b/include/boost/exception/diagnostic_information.hpp @@ -5,12 +5,6 @@ #ifndef UUID_0552D49838DD11DD90146B8956D89593 #define UUID_0552D49838DD11DD90146B8956D89593 -#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 #include #include @@ -22,9 +16,18 @@ #include #include #include - #ifndef BOOST_NO_EXCEPTIONS #include +#endif + +#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 + +#ifndef BOOST_NO_EXCEPTIONS namespace boost { diff --git a/include/boost/exception/enable_current_exception.hpp b/include/boost/exception/enable_current_exception.hpp index 9881053..495cc90 100644 --- a/include/boost/exception/enable_current_exception.hpp +++ b/include/boost/exception/enable_current_exception.hpp @@ -3,4 +3,9 @@ //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_851700A4F7CF11E6B2EE06DD14915323 +#define UUID_851700A4F7CF11E6B2EE06DD14915323 + #include + +#endif diff --git a/include/boost/exception/enable_error_info.hpp b/include/boost/exception/enable_error_info.hpp index 9881053..202217a 100644 --- a/include/boost/exception/enable_error_info.hpp +++ b/include/boost/exception/enable_error_info.hpp @@ -3,4 +3,9 @@ //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_A0F7404AF7CF11E6908227DD14915323 +#define UUID_A0F7404AF7CF11E6908227DD14915323 + #include + +#endif diff --git a/include/boost/exception/errinfo_errno.hpp b/include/boost/exception/errinfo_errno.hpp index de44e17..ebd8f25 100644 --- a/include/boost/exception/errinfo_errno.hpp +++ b/include/boost/exception/errinfo_errno.hpp @@ -5,6 +5,11 @@ #ifndef UUID_F0EE17BE6C1211DE87FF459155D89593 #define UUID_F0EE17BE6C1211DE87FF459155D89593 + +#include +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -13,10 +18,6 @@ #pragma warning(disable:4996) #endif -#include -#include -#include - namespace boost { diff --git a/include/boost/exception/get_error_info.hpp b/include/boost/exception/get_error_info.hpp index 51a21ba..831717d 100644 --- a/include/boost/exception/get_error_info.hpp +++ b/include/boost/exception/get_error_info.hpp @@ -5,6 +5,14 @@ #ifndef UUID_1A590226753311DD9E4CCF6156D89593 #define UUID_1A590226753311DD9E4CCF6156D89593 + +#include +#include +#include +#include +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,12 +20,6 @@ #pragma warning(push,1) #endif -#include -#include -#include -#include -#include - namespace boost { diff --git a/include/boost/exception/info.hpp b/include/boost/exception/info.hpp index f06df42..f7ac50e 100644 --- a/include/boost/exception/info.hpp +++ b/include/boost/exception/info.hpp @@ -5,6 +5,14 @@ #ifndef UUID_8D22C4CA9CC811DCAA9133D256D89593 #define UUID_8D22C4CA9CC811DCAA9133D256D89593 + +#include +#include +#include +#include +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,13 +20,6 @@ #pragma warning(push,1) #endif -#include -#include -#include -#include -#include -#include - namespace boost { @@ -38,45 +39,6 @@ boost return '[' + error_info_name(x) + "] = " + to_string_stub(x.value()) + '\n'; } - template - inline - error_info:: - error_info( value_type const & value ): - value_(value) - { - } - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - template - inline - error_info:: - error_info( error_info const & x ): - value_(x.value_) - { - } - template - inline - error_info:: - error_info( value_type && value ) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(value_type(std::move(value)))): - value_(std::move(value)) - { - } - template - inline - error_info:: - error_info( error_info && x ) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(value_type(std::move(x.value_)))): - value_(std::move(x.value_)) - { - } -#endif - - template - inline - error_info:: - ~error_info() throw() - { - } - template inline std::string @@ -180,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/include/boost/exception/info_tuple.hpp b/include/boost/exception/info_tuple.hpp index 70154fd..7c16d75 100644 --- a/include/boost/exception/info_tuple.hpp +++ b/include/boost/exception/info_tuple.hpp @@ -5,6 +5,10 @@ #ifndef UUID_63EE924290FB11DC87BB856555D89593 #define UUID_63EE924290FB11DC87BB856555D89593 + +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,9 +16,6 @@ #pragma warning(push,1) #endif -#include -#include - namespace boost { diff --git a/include/boost/exception/to_string.hpp b/include/boost/exception/to_string.hpp index 68541d2..51425b1 100644 --- a/include/boost/exception/to_string.hpp +++ b/include/boost/exception/to_string.hpp @@ -5,6 +5,11 @@ #ifndef UUID_7E48761AD92811DC9011477D56D89593 #define UUID_7E48761AD92811DC9011477D56D89593 + +#include +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,10 +17,6 @@ #pragma warning(push,1) #endif -#include -#include -#include - namespace boost { diff --git a/include/boost/exception/to_string_stub.hpp b/include/boost/exception/to_string_stub.hpp index b6ab31c..8ff5e47 100644 --- a/include/boost/exception/to_string_stub.hpp +++ b/include/boost/exception/to_string_stub.hpp @@ -5,6 +5,11 @@ #ifndef UUID_E788439ED9F011DCB181F25B55D89593 #define UUID_E788439ED9F011DCB181F25B55D89593 + +#include +#include +#include + #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) #pragma GCC system_header #endif @@ -12,10 +17,6 @@ #pragma warning(push,1) #endif -#include -#include -#include - namespace boost { diff --git a/src/clone_current_exception_non_intrusive.cpp b/src/clone_current_exception_non_intrusive.cpp index 1710cd7..7ebd7b5 100644 --- a/src/clone_current_exception_non_intrusive.cpp +++ b/src/clone_current_exception_non_intrusive.cpp @@ -10,18 +10,17 @@ #error This file requires exception handling to be enabled. #endif +#include #include -#if defined(BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR) && defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64) +#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! +//Thanks to Martin Weiss for implementing 64-bit support! #include #include -#ifndef BOOST_NO_RTTI -#include -#endif #include #include @@ -32,8 +31,10 @@ namespace #if _MSC_VER==1310 int const exception_info_offset=0x74; -#elif (_MSC_VER==1400 || _MSC_VER==1500) +#elif ((_MSC_VER==1400 || _MSC_VER==1500) && !defined _M_X64) int const exception_info_offset=0x80; +#elif ((_MSC_VER==1400 || _MSC_VER==1500) && defined _M_X64) + int const exception_info_offset=0xE0; #else int const exception_info_offset=-1; #endif @@ -58,7 +59,11 @@ namespace unsigned const cpp_exception_code=0xE06D7363; unsigned const cpp_exception_magic_flag=0x19930520; +#ifdef _M_X64 + unsigned const cpp_exception_parameter_count=4; +#else unsigned const cpp_exception_parameter_count=3; +#endif struct dummy_exception_type @@ -72,10 +77,18 @@ namespace union cpp_copy_constructor { + void * address; normal_copy_constructor_ptr normal_copy_constructor; copy_constructor_with_virtual_base_ptr copy_constructor_with_virtual_base; }; + union + cpp_destructor + { + void * address; + destructor_ptr destructor; + }; + enum cpp_type_flags { @@ -83,45 +96,46 @@ namespace class_has_virtual_base=4 }; + // ATTENTION: On x86 fields such as type_info and copy_constructor are really pointers + // but on 64bit these are 32bit offsets from HINSTANCE. Hints on the 64bit handling from + // http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx . struct cpp_type_info { unsigned flags; -#ifndef BOOST_NO_RTTI - void const * type_info; -#else - std::type_info * type_info; -#endif + int type_info; int this_offset; int vbase_descr; int vbase_offset; unsigned long size; - cpp_copy_constructor copy_constructor; + int copy_constructor; }; struct cpp_type_info_table { unsigned count; - const cpp_type_info * info[1]; + int info; }; struct cpp_exception_type { unsigned flags; - destructor_ptr destructor; - void(*custom_handler)(); - cpp_type_info_table const * type_info_table; + int destructor; + int custom_handler; + int type_info_table; }; struct exception_object_deleter { cpp_exception_type const & et_; + size_t image_base_; - exception_object_deleter( cpp_exception_type const & et ): - et_(et) + exception_object_deleter( cpp_exception_type const & et, size_t image_base ): + et_(et), + image_base_(image_base) { } @@ -129,45 +143,54 @@ namespace operator()( void * obj ) { BOOST_ASSERT(obj!=0); - dummy_exception_type * dummy_exception_ptr=reinterpret_cast(obj); - (dummy_exception_ptr->*(et_.destructor))(); + dummy_exception_type* dummy_exception_ptr = static_cast(obj); + if( et_.destructor ) + { + cpp_destructor destructor; + destructor.address = reinterpret_cast(et_.destructor + image_base_); + (dummy_exception_ptr->*(destructor.destructor))(); + } free(obj); } }; cpp_type_info const & - get_cpp_type_info( cpp_exception_type const & et ) + get_cpp_type_info( cpp_exception_type const & et, size_t image_base ) { - cpp_type_info const * ti = et.type_info_table->info[0]; + cpp_type_info_table * const typearray = reinterpret_cast(et.type_info_table + image_base); + cpp_type_info * const ti = reinterpret_cast(typearray->info + image_base); BOOST_ASSERT(ti!=0); return *ti; } void - copy_msvc_exception( void * dst, void * src, cpp_type_info const & ti ) + copy_msvc_exception( void * dst, void * src, cpp_type_info const & ti, size_t image_base ) { - if( !(ti.flags & class_is_simple_type) && ti.copy_constructor.normal_copy_constructor ) + cpp_copy_constructor copy_constructor; + copy_constructor.address = reinterpret_cast(ti.copy_constructor + image_base); + + if( !(ti.flags & class_is_simple_type) && copy_constructor.normal_copy_constructor ) { - dummy_exception_type * dummy_exception_ptr = reinterpret_cast(dst); + dummy_exception_type * dummy_exception_ptr = static_cast(dst); if( ti.flags & class_has_virtual_base ) - (dummy_exception_ptr->*(ti.copy_constructor.copy_constructor_with_virtual_base))(src,dst); + (dummy_exception_ptr->*(copy_constructor.copy_constructor_with_virtual_base))(src,dst); else - (dummy_exception_ptr->*(ti.copy_constructor.normal_copy_constructor))(src); + (dummy_exception_ptr->*(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 ) + clone_msvc_exception( void * src, cpp_exception_type const & et, size_t image_base ) { - assert(src!=0); - cpp_type_info const & ti=get_cpp_type_info(et); + BOOST_ASSERT(src!=0); + cpp_type_info const & ti=get_cpp_type_info(et,image_base); if( void * dst = malloc(ti.size) ) { try { - copy_msvc_exception(dst,src,ti); + copy_msvc_exception(dst,src,ti,image_base); } catch( ... ) @@ -175,7 +198,7 @@ namespace free(dst); throw; } - return boost::shared_ptr(dst,exception_object_deleter(et)); + return boost::shared_ptr(dst,exception_object_deleter(et,image_base)); } else throw std::bad_alloc(); @@ -189,13 +212,21 @@ namespace cloned_exception & operator=( cloned_exception const & ); cpp_exception_type const & et_; + size_t image_base_; boost::shared_ptr exc_; public: + cloned_exception( EXCEPTION_RECORD const * record ): + et_(*reinterpret_cast(record->ExceptionInformation[2])), + image_base_((cpp_exception_parameter_count==4) ? record->ExceptionInformation[3] : 0), + exc_(clone_msvc_exception(reinterpret_cast(record->ExceptionInformation[1]),et_,image_base_)) + { + } - cloned_exception( void * exc, cpp_exception_type const & et ): + cloned_exception( void * exc, cpp_exception_type const & et, size_t image_base ): et_(et), - exc_(clone_msvc_exception(exc,et_)) + image_base_(image_base), + exc_(clone_msvc_exception(exc,et_,image_base)) { } @@ -206,19 +237,22 @@ namespace boost::exception_detail::clone_base const * clone() const { - return new cloned_exception(exc_.get(),et_); + return new cloned_exception(exc_.get(),et_,image_base_); } void rethrow() const { - cpp_type_info const & ti=get_cpp_type_info(et_); + cpp_type_info const & ti=get_cpp_type_info(et_,image_base_); void * dst = _alloca(ti.size); - copy_msvc_exception(dst,exc_.get(),ti); + copy_msvc_exception(dst,exc_.get(),ti,image_base_); ULONG_PTR args[cpp_exception_parameter_count]; args[0]=cpp_exception_magic_flag; args[1]=reinterpret_cast(dst); args[2]=reinterpret_cast(&et_); + if (cpp_exception_parameter_count==4) + args[3]=image_base_; + RaiseException(cpp_exception_code,EXCEPTION_NONCONTINUABLE,cpp_exception_parameter_count,args); } }; @@ -237,8 +271,7 @@ namespace { BOOST_ASSERT(exception_info_offset>=0); BOOST_ASSERT(info_!=0); - EXCEPTION_POINTERS * info=reinterpret_cast(info_); - EXCEPTION_RECORD * record=info->ExceptionRecord; + EXCEPTION_RECORD* record = static_cast(info_)->ExceptionRecord; if( is_cpp_exception(record) ) { if( !record->ExceptionInformation[2] ) @@ -246,9 +279,7 @@ namespace if( is_cpp_exception(record) && record->ExceptionInformation[2] ) try { - ptr = new cloned_exception( - reinterpret_cast(record->ExceptionInformation[1]), - *reinterpret_cast(record->ExceptionInformation[2])); + ptr = new cloned_exception(record); result = boost::exception_detail::clone_current_exception_result::success; } catch( @@ -301,8 +332,6 @@ boost //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 { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e7cf00d..53d277f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -34,6 +34,7 @@ run exception_test.cpp ; run enable_error_info_test.cpp helper1.cpp ; run throw_exception_test.cpp helper2.cpp ; run errno_test.cpp ; +run error_info_basic_test.cpp ; run error_info_lv_test.cpp ; run error_info_lv_const_test.cpp ; run error_info_rv_test.cpp ; diff --git a/test/error_info_basic_test.cpp b/test/error_info_basic_test.cpp new file mode 100644 index 0000000..aa8d6a7 --- /dev/null +++ b/test/error_info_basic_test.cpp @@ -0,0 +1,29 @@ +//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) + +#include +#include +#include +#include +#include +#include +#include + +struct my_exception: virtual boost::exception {}; +typedef boost::error_info error_info_string; + +int +main() + { + try + { + throw my_exception() << error_info_string("doh"); + } + catch( my_exception & e ) + { + BOOST_TEST(boost::get_error_info(e) && !strcmp(boost::get_error_info(e)->c_str(),"doh")); + } + return 0; + } diff --git a/test/exception_hpp_test.cpp b/test/exception_hpp_test.cpp deleted file mode 100644 index 6f77efe..0000000 --- a/test/exception_hpp_test.cpp +++ /dev/null @@ -1,7 +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) - -#include -#include diff --git a/test/exception_ptr_test.cpp b/test/exception_ptr_test.cpp index 193fabc..367558c 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 {