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( disable : 4793 ) // complaint about native code generation
# pragma warning( disable : 4127 ) // "conditional expression is constant"
#endif
#endif
#if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG)
# define BOOST_FUNCTION_TARGET_FIX(x) x
@ -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,28 +287,28 @@ 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 */ {
out_buffer.type.type = &boost::typeindex::type_id<Functor>().type_info();
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)
# pragma warning( pop )
#endif
#endif
#endif // BOOST_FUNCTION_BASE_HEADER

View File

@ -16,7 +16,7 @@
#if defined(BOOST_MSVC)
# pragma warning( push )
# 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)
@ -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
@ -752,14 +752,14 @@ namespace boost {
{
this->assign_to_own(f);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
{
this->move_assign(f);
}
#endif
~BOOST_FUNCTION_FUNCTION() { clear(); }
result_type operator()(BOOST_FUNCTION_PARMS) const
@ -840,12 +840,11 @@ namespace boost {
BOOST_CATCH_END
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Move assignment from another BOOST_FUNCTION_FUNCTION
BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
{
if (&f == this)
return *this;
@ -925,7 +924,7 @@ namespace boost {
template apply<Functor, R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>
handler_type;
typedef typename handler_type::invoker_type invoker_type;
typedef typename handler_type::manager_type manager_type;
@ -960,7 +959,7 @@ namespace boost {
BOOST_FUNCTION_TEMPLATE_ARGS,
Allocator>
handler_type;
typedef typename handler_type::invoker_type invoker_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
// its buffer to *this, and set the argument's buffer pointer to NULL.
void move_assign(BOOST_FUNCTION_FUNCTION& f)
{
{
if (&f == this)
return;
@ -1098,7 +1097,7 @@ public:
function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
#endif
self_type& operator=(const self_type& f)
{
self_type(f).swap(*this);
@ -1111,7 +1110,7 @@ public:
self_type(static_cast<self_type&&>(f)).swap(*this);
return *this;
}
#endif
#endif
template<typename Functor>
#ifndef BOOST_NO_SFINAE
@ -1147,7 +1146,7 @@ public:
self_type(static_cast<base_type&&>(f)).swap(*this);
return *this;
}
#endif
#endif
};
#undef BOOST_FUNCTION_PARTIAL_SPEC
@ -1187,4 +1186,4 @@ public:
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif
#endif