Removing non-intrusive exception_ptr support.

This commit is contained in:
Emil Dotchevski
2017-03-13 15:07:09 -07:00
parent 4ea8555871
commit cf05dc079b
8 changed files with 173 additions and 557 deletions

View File

@ -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 <link>static
;
lib boost_exception : clone_current_exception_non_intrusive.cpp ;
boost-install boost_exception ;

View File

@ -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 <boost/config.hpp>
#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

View File

@ -14,7 +14,6 @@
#include <boost/exception/info.hpp> #include <boost/exception/info.hpp>
#include <boost/exception/diagnostic_information.hpp> #include <boost/exception/diagnostic_information.hpp>
#include <boost/exception/detail/type_info.hpp> #include <boost/exception/detail/type_info.hpp>
#include <boost/exception/detail/clone_current_exception.hpp>
#ifndef BOOST_NO_RTTI #ifndef BOOST_NO_RTTI
#include <boost/core/demangle.hpp> #include <boost/core/demangle.hpp>
#endif #endif
@ -303,131 +302,101 @@ boost
exception_ptr exception_ptr
current_exception_impl() current_exception_impl()
{ {
exception_detail::clone_base const * e=0; try
switch(
exception_detail::clone_current_exception(e) )
{ {
case exception_detail::clone_current_exception_result:: throw;
success: }
{ catch(
BOOST_ASSERT(e!=0); exception_detail::clone_base & e )
return exception_ptr(shared_ptr<exception_detail::clone_base const>(e)); {
} return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone()));
case exception_detail::clone_current_exception_result:: }
bad_alloc: catch(
{ std::domain_error & e )
BOOST_ASSERT(!e); {
return exception_detail::exception_ptr_static_exception_object<bad_alloc_>::e; return exception_detail::current_exception_std_exception(e);
} }
case exception_detail::clone_current_exception_result:: catch(
bad_exception: std::invalid_argument & e )
{ {
BOOST_ASSERT(!e); return exception_detail::current_exception_std_exception(e);
return exception_detail::exception_ptr_static_exception_object<bad_exception_>::e; }
} catch(
default: std::length_error & e )
BOOST_ASSERT(0); {
case exception_detail::clone_current_exception_result:: return exception_detail::current_exception_std_exception(e);
not_supported: }
{ catch(
BOOST_ASSERT(!e); std::out_of_range & e )
try {
{ return exception_detail::current_exception_std_exception(e);
throw; }
} catch(
catch( std::logic_error & e )
exception_detail::clone_base & e ) {
{ return exception_detail::current_exception_std_exception(e);
return exception_ptr(shared_ptr<exception_detail::clone_base const>(e.clone())); }
} catch(
catch( std::range_error & e )
std::domain_error & e ) {
{ return exception_detail::current_exception_std_exception(e);
return exception_detail::current_exception_std_exception(e); }
} catch(
catch( std::overflow_error & e )
std::invalid_argument & e ) {
{ return exception_detail::current_exception_std_exception(e);
return exception_detail::current_exception_std_exception(e); }
} catch(
catch( std::underflow_error & e )
std::length_error & e ) {
{ return exception_detail::current_exception_std_exception(e);
return exception_detail::current_exception_std_exception(e); }
} catch(
catch( std::ios_base::failure & e )
std::out_of_range & e ) {
{ return exception_detail::current_exception_std_exception(e);
return exception_detail::current_exception_std_exception(e); }
} catch(
catch( std::runtime_error & e )
std::logic_error & e ) {
{ return exception_detail::current_exception_std_exception(e);
return exception_detail::current_exception_std_exception(e); }
} catch(
catch( std::bad_alloc & e )
std::range_error & e ) {
{ return exception_detail::current_exception_std_exception(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 #ifndef BOOST_NO_TYPEID
catch( catch(
std::bad_cast & e ) std::bad_cast & e )
{ {
return exception_detail::current_exception_std_exception(e); return exception_detail::current_exception_std_exception(e);
} }
catch( catch(
std::bad_typeid & e ) std::bad_typeid & e )
{ {
return exception_detail::current_exception_std_exception(e); return exception_detail::current_exception_std_exception(e);
} }
#endif #endif
catch( catch(
std::bad_exception & e ) std::bad_exception & e )
{ {
return exception_detail::current_exception_std_exception(e); return exception_detail::current_exception_std_exception(e);
} }
catch( catch(
std::exception & e ) std::exception & e )
{ {
return exception_detail::current_exception_unknown_std_exception(e); return exception_detail::current_exception_unknown_std_exception(e);
} }
catch( catch(
boost::exception & e ) boost::exception & e )
{ {
return exception_detail::current_exception_unknown_boost_exception(e); return exception_detail::current_exception_unknown_boost_exception(e);
} }
catch( catch(
... ) ... )
{ {
return exception_detail::current_exception_unknown_exception(); return exception_detail::current_exception_unknown_exception();
}
}
} }
} }
} }

View File

@ -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<void> v_;
public:
explicit
template <class T>
exception_datum( T const & v ):
ti_(typeid(T)),
v_(make_shared<T>(v))
{
}
template <class T>
T *
cast()
{
if( typeid(T)==ti_ )
return static_cast<T *>(v_.get());
else
return 0;
}
};
class
exception_data
{
std::map<std::string,exception_datum> data_;
protected:
exception_data()
{
}
~exception_data()
{
}
public:
template <class T>
exception_data &
set( char const * tag, T const & value )
{
data_[tag]=exception_datum(value);
return *this;
}
template <class T>
T const *
get( char const * tag ) const
{
auto it=data_.find(tag);
if( it!=data_.end() )
return it->cast<T>();
else
return 0;
}
};
}
catch(
exception_data & d )
{
d["file_name"].set<std::string>("foo.txt");
d["file_name"].get<std::string>();
d.set<std::string>("file_name","foo.txt");
throw;
}
throw_exception(foo_error(),make_pair<std::string,int>("errno",errno),pair<std::string,float>("width",width));
#endif

View File

@ -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 <boost/exception/detail/clone_current_exception.hpp>
#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 <boost/exception/exception.hpp>
#include <boost/shared_ptr.hpp>
#ifndef BOOST_NO_RTTI
#include <typeinfo>
#endif
#include <windows.h>
#include <malloc.h>
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<dummy_exception_type *>(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<dummy_exception_type *>(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<void>
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<void>(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<void> 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<ULONG_PTR>(dst);
args[2]=reinterpret_cast<ULONG_PTR>(&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<EXCEPTION_POINTERS *>(info_);
EXCEPTION_RECORD * record=info->ExceptionRecord;
if( is_cpp_exception(record) )
{
if( !record->ExceptionInformation[2] )
record = *reinterpret_cast<EXCEPTION_RECORD * *>(reinterpret_cast<char *>(_errno())+exception_info_offset);
if( is_cpp_exception(record) && record->ExceptionInformation[2] )
try
{
ptr = new cloned_exception(
reinterpret_cast<void *>(record->ExceptionInformation[1]),
*reinterpret_cast<cpp_exception_type const *>(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 <boost/config.hpp>
namespace
boost
{
namespace
exception_detail
{
int
clone_current_exception_non_intrusive( clone_base const * & )
{
return clone_current_exception_result::not_supported;
}
}
}
#endif

View File

@ -44,7 +44,6 @@ run refcount_ptr_test.cpp ;
run current_exception_cast_test.cpp ; run current_exception_cast_test.cpp ;
run no_exceptions_test.cpp : : : <exception-handling>off ; run no_exceptions_test.cpp : : : <exception-handling>off ;
run errinfos_test.cpp ; run errinfos_test.cpp ;
run exception_ptr_test.cpp/<define>BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR ../../thread/src/tss_null.cpp /boost/exception /boost//thread : : : <threading>multi : non_intrusive_exception_ptr_test ;
run exception_ptr_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : <threading>multi ; run exception_ptr_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : <threading>multi ;
run N3757_test.cpp ; run N3757_test.cpp ;

View File

@ -395,11 +395,6 @@ main()
BOOST_TEST(false); BOOST_TEST(false);
} }
catch( catch(
derives_std_exception & )
{
//Yay! Non-intrusive cloning supported!
}
catch(
boost::unknown_exception & e ) boost::unknown_exception & e )
{ {
#ifndef BOOST_NO_RTTI #ifndef BOOST_NO_RTTI
@ -449,14 +444,6 @@ main()
BOOST_TEST(false); BOOST_TEST(false);
} }
catch( catch(
derives_std_boost_exception & x )
{
//Yay! Non-intrusive cloning supported!
BOOST_TEST(boost::get_error_info<my_info>(x));
if( int const * p=boost::get_error_info<my_info>(x) )
BOOST_TEST(*p==42);
}
catch(
boost::unknown_exception & x ) boost::unknown_exception & x )
{ {
BOOST_TEST(boost::get_error_info<my_info>(x)); BOOST_TEST(boost::get_error_info<my_info>(x));
@ -518,14 +505,6 @@ main()
BOOST_TEST(false); BOOST_TEST(false);
} }
catch( catch(
derives_boost_exception & x )
{
//Yay! Non-intrusive cloning supported!
BOOST_TEST(boost::get_error_info<my_info>(x));
if( int const * p=boost::get_error_info<my_info>(x) )
BOOST_TEST(*p==42);
}
catch(
boost::unknown_exception & x ) boost::unknown_exception & x )
{ {
BOOST_TEST(boost::get_error_info<my_info>(x)); BOOST_TEST(boost::get_error_info<my_info>(x));

View File

@ -62,15 +62,6 @@ main()
BOOST_TEST(false); BOOST_TEST(false);
} }
catch( catch(
boost::exception & x )
{
//Yay! Non-intrusive cloning supported!
if( int const * d=boost::get_error_info<test>(x) )
BOOST_TEST( 42==*d );
else
BOOST_TEST(false);
}
catch(
... ) ... )
{ {
BOOST_TEST(false); BOOST_TEST(false);
@ -110,11 +101,6 @@ main()
{ {
} }
catch( catch(
std::exception & )
{
//Yay! Non-intrusive cloning supported!
}
catch(
... ) ... )
{ {
BOOST_TEST(false); BOOST_TEST(false);
@ -128,11 +114,6 @@ main()
{ {
} }
catch( catch(
std::exception & )
{
//Yay! Non-intrusive cloning supported!
}
catch(
... ) ... )
{ {
BOOST_TEST(false); BOOST_TEST(false);