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

@ -41,7 +41,7 @@
# pragma warning( push ) # pragma warning( push )
# pragma warning( disable : 4793 ) // complaint about native code generation # pragma warning( disable : 4793 ) // complaint about native code generation
# pragma warning( disable : 4127 ) // "conditional expression is constant" # pragma warning( disable : 4127 ) // "conditional expression is constant"
#endif #endif
#if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG) #if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG)
# define BOOST_FUNCTION_TARGET_FIX(x) x # define BOOST_FUNCTION_TARGET_FIX(x) x
@ -68,7 +68,8 @@ namespace boost {
union function_buffer union function_buffer
{ {
// For pointers to function objects // 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 // For pointers to std::type_info objects
struct type_t { struct type_t {
@ -82,7 +83,8 @@ namespace boost {
} type; } type;
// For function pointers of all kinds // 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 // For bound member pointers
struct bound_memfunc_ptr_t { struct bound_memfunc_ptr_t {
@ -98,8 +100,16 @@ namespace boost {
bool is_volatile_qualified; bool is_volatile_qualified;
} obj_ref; } 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 // To relax aliasing constraints
mutable char data; mutable char data[data_size];
}; };
/** /**
@ -277,28 +287,28 @@ namespace boost {
{ {
if (op == clone_functor_tag || op == move_functor_tag) { if (op == clone_functor_tag || op == move_functor_tag) {
const functor_type* in_functor = const functor_type* in_functor =
reinterpret_cast<const functor_type*>(&in_buffer.data); reinterpret_cast<const functor_type*>(in_buffer.data);
new (reinterpret_cast<void*>(&out_buffer.data)) functor_type(*in_functor); new (reinterpret_cast<void*>(out_buffer.data)) functor_type(*in_functor);
if (op == move_functor_tag) { 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) (void)f; // suppress warning about the value of f not being used (MSVC)
f->~Functor(); f->~Functor();
} }
} else if (op == destroy_functor_tag) { } else if (op == destroy_functor_tag) {
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. // 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) (void)f; // suppress warning about the value of f not being used (MSVC)
f->~Functor(); f->~Functor();
} else if (op == check_functor_type_tag) { } else if (op == check_functor_type_tag) {
if (*out_buffer.type.type == boost::typeindex::type_id<Functor>()) 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 else
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ { } else /* op == get_functor_type_tag */ {
out_buffer.type.type = &boost::typeindex::type_id<Functor>().type_info(); out_buffer.type.type = &boost::typeindex::type_id<Functor>().type_info();
out_buffer.type.const_qualified = false; out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false; out_buffer.type.volatile_qualified = false;
} }
} }
}; };
@ -853,6 +863,6 @@ namespace detail {
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
# pragma warning( pop ) # pragma warning( pop )
#endif #endif
#endif // BOOST_FUNCTION_BASE_HEADER #endif // BOOST_FUNCTION_BASE_HEADER

View File

@ -16,7 +16,7 @@
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
# pragma warning( push ) # pragma warning( push )
# pragma warning( disable : 4127 ) // "conditional expression is constant" # pragma warning( disable : 4127 ) // "conditional expression is constant"
#endif #endif
#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
@ -132,7 +132,7 @@ namespace boost {
{ {
FunctionObj* f; FunctionObj* f;
if (function_allows_small_object_optimization<FunctionObj>::value) 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 else
f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr); f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
return (*f)(BOOST_FUNCTION_ARGS); return (*f)(BOOST_FUNCTION_ARGS);
@ -153,7 +153,7 @@ namespace boost {
{ {
FunctionObj* f; FunctionObj* f;
if (function_allows_small_object_optimization<FunctionObj>::value) 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 else
f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr); f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
@ -209,7 +209,7 @@ namespace boost {
{ {
MemberPtr* f = MemberPtr* f =
reinterpret_cast<MemberPtr*>(&function_obj_ptr.data); reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
} }
}; };
@ -227,7 +227,7 @@ namespace boost {
{ {
MemberPtr* f = 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)); BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
} }
}; };
@ -569,7 +569,7 @@ namespace boost {
void void
assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const 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> template<typename FunctionObj,typename Allocator>
void void
@ -752,14 +752,14 @@ namespace boost {
{ {
this->assign_to_own(f); this->assign_to_own(f);
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base() BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
{ {
this->move_assign(f); this->move_assign(f);
} }
#endif #endif
~BOOST_FUNCTION_FUNCTION() { clear(); } ~BOOST_FUNCTION_FUNCTION() { clear(); }
result_type operator()(BOOST_FUNCTION_PARMS) const result_type operator()(BOOST_FUNCTION_PARMS) const
@ -840,12 +840,11 @@ namespace boost {
BOOST_CATCH_END BOOST_CATCH_END
return *this; return *this;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Move assignment from another BOOST_FUNCTION_FUNCTION // Move assignment from another BOOST_FUNCTION_FUNCTION
BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f) BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
{ {
if (&f == this) if (&f == this)
return *this; return *this;
@ -925,7 +924,7 @@ namespace boost {
template apply<Functor, R BOOST_FUNCTION_COMMA template apply<Functor, R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS> BOOST_FUNCTION_TEMPLATE_ARGS>
handler_type; handler_type;
typedef typename handler_type::invoker_type invoker_type; typedef typename handler_type::invoker_type invoker_type;
typedef typename handler_type::manager_type manager_type; typedef typename handler_type::manager_type manager_type;
@ -960,7 +959,7 @@ namespace boost {
BOOST_FUNCTION_TEMPLATE_ARGS, BOOST_FUNCTION_TEMPLATE_ARGS,
Allocator> Allocator>
handler_type; handler_type;
typedef typename handler_type::invoker_type invoker_type; typedef typename handler_type::invoker_type invoker_type;
typedef typename handler_type::manager_type manager_type; typedef typename handler_type::manager_type manager_type;
@ -987,7 +986,7 @@ namespace boost {
// has its function object allocated on the heap, move_assign will pass // has its function object allocated on the heap, move_assign will pass
// its buffer to *this, and set the argument's buffer pointer to NULL. // its buffer to *this, and set the argument's buffer pointer to NULL.
void move_assign(BOOST_FUNCTION_FUNCTION& f) void move_assign(BOOST_FUNCTION_FUNCTION& f)
{ {
if (&f == this) if (&f == this)
return; return;
@ -1098,7 +1097,7 @@ public:
function(self_type&& f): base_type(static_cast<base_type&&>(f)){} function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
function(base_type&& f): base_type(static_cast<base_type&&>(f)){} function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
#endif #endif
self_type& operator=(const self_type& f) self_type& operator=(const self_type& f)
{ {
self_type(f).swap(*this); self_type(f).swap(*this);
@ -1111,7 +1110,7 @@ public:
self_type(static_cast<self_type&&>(f)).swap(*this); self_type(static_cast<self_type&&>(f)).swap(*this);
return *this; return *this;
} }
#endif #endif
template<typename Functor> template<typename Functor>
#ifndef BOOST_NO_SFINAE #ifndef BOOST_NO_SFINAE
@ -1147,7 +1146,7 @@ public:
self_type(static_cast<base_type&&>(f)).swap(*this); self_type(static_cast<base_type&&>(f)).swap(*this);
return *this; return *this;
} }
#endif #endif
}; };
#undef BOOST_FUNCTION_PARTIAL_SPEC #undef BOOST_FUNCTION_PARTIAL_SPEC
@ -1187,4 +1186,4 @@ public:
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
# pragma warning( pop ) # pragma warning( pop )
#endif #endif