Fix gcc 6 warnings about invoking placement new on a buffer of insufficient size.

This commit is contained in:
Andrey Semashev
2016-04-02 14:59:57 +03:00
parent 3eb8954877
commit bde64bf9eb
2 changed files with 37 additions and 28 deletions

View File

@ -68,7 +68,8 @@ namespace boost {
union function_buffer
{
// For pointers to function objects
mutable void* obj_ptr;
typedef void* obj_ptr_t;
mutable obj_ptr_t obj_ptr;
// For pointers to std::type_info objects
struct type_t {
@ -82,7 +83,8 @@ namespace boost {
} type;
// For function pointers of all kinds
mutable void (*func_ptr)();
typedef void (*func_ptr_t)();
mutable func_ptr_t func_ptr;
// For bound member pointers
struct bound_memfunc_ptr_t {
@ -98,8 +100,16 @@ namespace boost {
bool is_volatile_qualified;
} obj_ref;
enum {
size1 = sizeof(obj_ptr_t) > sizeof(type_t) ? sizeof(obj_ptr_t) : sizeof(type_t),
size2 = size1 > sizeof(func_ptr_t) ? size1 : sizeof(func_ptr_t),
size3 = size2 > sizeof(bound_memfunc_ptr_t) ? size2 : sizeof(bound_memfunc_ptr_t),
size4 = size3 > sizeof(obj_ref_t) ? size3 : sizeof(obj_ref_t),
data_size = size4
};
// To relax aliasing constraints
mutable char data;
mutable char data[data_size];
};
/**
@ -277,22 +287,22 @@ namespace boost {
{
if (op == clone_functor_tag || op == move_functor_tag) {
const functor_type* in_functor =
reinterpret_cast<const functor_type*>(&in_buffer.data);
new (reinterpret_cast<void*>(&out_buffer.data)) functor_type(*in_functor);
reinterpret_cast<const functor_type*>(in_buffer.data);
new (reinterpret_cast<void*>(out_buffer.data)) functor_type(*in_functor);
if (op == move_functor_tag) {
functor_type* f = reinterpret_cast<functor_type*>(&in_buffer.data);
functor_type* f = reinterpret_cast<functor_type*>(in_buffer.data);
(void)f; // suppress warning about the value of f not being used (MSVC)
f->~Functor();
}
} else if (op == destroy_functor_tag) {
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
functor_type* f = reinterpret_cast<functor_type*>(&out_buffer.data);
functor_type* f = reinterpret_cast<functor_type*>(out_buffer.data);
(void)f; // suppress warning about the value of f not being used (MSVC)
f->~Functor();
} else if (op == check_functor_type_tag) {
if (*out_buffer.type.type == boost::typeindex::type_id<Functor>())
out_buffer.obj_ptr = &in_buffer.data;
out_buffer.obj_ptr = in_buffer.data;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {

View File

@ -132,7 +132,7 @@ namespace boost {
{
FunctionObj* f;
if (function_allows_small_object_optimization<FunctionObj>::value)
f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
else
f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
return (*f)(BOOST_FUNCTION_ARGS);
@ -153,7 +153,7 @@ namespace boost {
{
FunctionObj* f;
if (function_allows_small_object_optimization<FunctionObj>::value)
f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
else
f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
@ -209,7 +209,7 @@ namespace boost {
{
MemberPtr* f =
reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
}
};
@ -227,7 +227,7 @@ namespace boost {
{
MemberPtr* f =
reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
}
};
@ -569,7 +569,7 @@ namespace boost {
void
assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const
{
new (reinterpret_cast<void*>(&functor.data)) FunctionObj(f);
new (reinterpret_cast<void*>(functor.data)) FunctionObj(f);
}
template<typename FunctionObj,typename Allocator>
void
@ -845,7 +845,6 @@ namespace boost {
// Move assignment from another BOOST_FUNCTION_FUNCTION
BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
{
if (&f == this)
return *this;