mirror of
https://github.com/boostorg/container.git
synced 2025-08-03 14:34:27 +02:00
Corrected strict aliasing error in multiallocation_chain
[SVN r80514]
This commit is contained in:
@@ -348,8 +348,7 @@ class private_adaptive_node_pool_impl
|
|||||||
{
|
{
|
||||||
block_iterator block_it(m_block_multiset.end());
|
block_iterator block_it(m_block_multiset.end());
|
||||||
while(n--){
|
while(n--){
|
||||||
void *pElem = container_detail::to_raw_pointer(chain.front());
|
void *pElem = container_detail::to_raw_pointer(chain.pop_front());
|
||||||
chain.pop_front();
|
|
||||||
priv_invariants();
|
priv_invariants();
|
||||||
block_info_t *block_info = this->priv_block_from_node(pElem);
|
block_info_t *block_info = this->priv_block_from_node(pElem);
|
||||||
BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
|
BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
|
||||||
|
@@ -45,14 +45,30 @@ class basic_multiallocation_chain
|
|||||||
> slist_impl_t;
|
> slist_impl_t;
|
||||||
slist_impl_t slist_impl_;
|
slist_impl_t slist_impl_;
|
||||||
|
|
||||||
static node & to_node(VoidPointer p)
|
typedef typename boost::intrusive::pointer_traits
|
||||||
{ return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
|
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
|
||||||
|
typedef typename boost::intrusive::
|
||||||
|
pointer_traits<node_ptr> node_ptr_traits;
|
||||||
|
|
||||||
|
static node & build_node(const VoidPointer &p)
|
||||||
|
{
|
||||||
|
return *::new (static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p)))) node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VoidPointer destroy_node(node &n)
|
||||||
|
{
|
||||||
|
VoidPointer retptr = node_ptr_traits::pointer_to(n);
|
||||||
|
n.~node();
|
||||||
|
return retptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static node_ptr to_node_ptr(VoidPointer p)
|
||||||
|
{ return node_ptr_traits::static_cast_from(p); }
|
||||||
|
|
||||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
|
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
typedef VoidPointer void_pointer;
|
typedef VoidPointer void_pointer;
|
||||||
typedef typename slist_impl_t::iterator iterator;
|
typedef typename slist_impl_t::iterator iterator;
|
||||||
typedef typename slist_impl_t::size_type size_type;
|
typedef typename slist_impl_t::size_type size_type;
|
||||||
@@ -94,19 +110,21 @@ class basic_multiallocation_chain
|
|||||||
{ slist_impl_.clear(); }
|
{ slist_impl_.clear(); }
|
||||||
|
|
||||||
iterator insert_after(iterator it, void_pointer m)
|
iterator insert_after(iterator it, void_pointer m)
|
||||||
{ return slist_impl_.insert_after(it, to_node(m)); }
|
{ return slist_impl_.insert_after(it, build_node(m)); }
|
||||||
|
|
||||||
void push_front(void_pointer m)
|
void push_front(void_pointer m)
|
||||||
{ return slist_impl_.push_front(to_node(m)); }
|
{ return slist_impl_.push_front(build_node(m)); }
|
||||||
|
|
||||||
void push_back(void_pointer m)
|
void push_back(void_pointer m)
|
||||||
{ return slist_impl_.push_back(to_node(m)); }
|
{ return slist_impl_.push_back(build_node(m)); }
|
||||||
|
|
||||||
void pop_front()
|
void_pointer pop_front()
|
||||||
{ return slist_impl_.pop_front(); }
|
{
|
||||||
|
node & n = slist_impl_.front();
|
||||||
void *front()
|
void_pointer ret = destroy_node(n);
|
||||||
{ return &*slist_impl_.begin(); }
|
slist_impl_.pop_front();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end)
|
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end)
|
||||||
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end); }
|
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end); }
|
||||||
@@ -118,10 +136,12 @@ class basic_multiallocation_chain
|
|||||||
{ slist_impl_.splice_after(after_this, x.slist_impl_); }
|
{ slist_impl_.splice_after(after_this, x.slist_impl_); }
|
||||||
|
|
||||||
void incorporate_after(iterator after_this, void_pointer begin , iterator before_end)
|
void incorporate_after(iterator after_this, void_pointer begin , iterator before_end)
|
||||||
{ slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end)); }
|
{
|
||||||
|
slist_impl_.incorporate_after(after_this, to_node_ptr(begin), to_node_ptr(before_end));
|
||||||
|
}
|
||||||
|
|
||||||
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
|
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
|
||||||
{ slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end), n); }
|
{ slist_impl_.incorporate_after(after_this, to_node_ptr(begin), to_node_ptr(before_end), n); }
|
||||||
|
|
||||||
void swap(basic_multiallocation_chain &x)
|
void swap(basic_multiallocation_chain &x)
|
||||||
{ slist_impl_.swap(x.slist_impl_); }
|
{ slist_impl_.swap(x.slist_impl_); }
|
||||||
@@ -203,11 +223,8 @@ class transform_multiallocation_chain
|
|||||||
void incorporate_after(iterator after_this, pointer begin, pointer before_end, size_type n)
|
void incorporate_after(iterator after_this, pointer begin, pointer before_end, size_type n)
|
||||||
{ holder_.incorporate_after(after_this.base(), begin, before_end, n); }
|
{ holder_.incorporate_after(after_this.base(), begin, before_end, n); }
|
||||||
|
|
||||||
void pop_front()
|
pointer pop_front()
|
||||||
{ holder_.pop_front(); }
|
{ return cast(holder_.pop_front()); }
|
||||||
|
|
||||||
pointer front()
|
|
||||||
{ return cast(holder_.front()); }
|
|
||||||
|
|
||||||
bool empty() const
|
bool empty() const
|
||||||
{ return holder_.empty(); }
|
{ return holder_.empty(); }
|
||||||
|
@@ -247,8 +247,7 @@ struct node_alloc_holder
|
|||||||
Node *p = 0;
|
Node *p = 0;
|
||||||
BOOST_TRY{
|
BOOST_TRY{
|
||||||
for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
|
for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
|
||||||
p = container_detail::to_raw_pointer(mem.front());
|
p = container_detail::to_raw_pointer(mem.pop_front());
|
||||||
mem.pop_front();
|
|
||||||
//This can throw
|
//This can throw
|
||||||
constructed = 0;
|
constructed = 0;
|
||||||
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
|
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
|
||||||
|
@@ -589,9 +589,7 @@ class stable_vector
|
|||||||
::value>::type * = 0)
|
::value>::type * = 0)
|
||||||
{
|
{
|
||||||
while(!holder.empty()){
|
while(!holder.empty()){
|
||||||
const node_ptr n = holder.front();
|
this->deallocate_one(holder.pop_front());
|
||||||
holder.pop_front();
|
|
||||||
this->deallocate_one(n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1697,8 +1695,7 @@ class stable_vector
|
|||||||
, node_ptr_traits::static_cast_from(pool_first_ref)
|
, node_ptr_traits::static_cast_from(pool_first_ref)
|
||||||
, node_ptr_traits::static_cast_from(pool_last_ref)
|
, node_ptr_traits::static_cast_from(pool_last_ref)
|
||||||
, internal_data.pool_size);
|
, internal_data.pool_size);
|
||||||
node_ptr ret = holder.front();
|
node_ptr ret = holder.pop_front();
|
||||||
holder.pop_front();
|
|
||||||
--this->internal_data.pool_size;
|
--this->internal_data.pool_size;
|
||||||
if(!internal_data.pool_size){
|
if(!internal_data.pool_size){
|
||||||
pool_first_ref = pool_last_ref = node_ptr();
|
pool_first_ref = pool_last_ref = node_ptr();
|
||||||
|
@@ -1723,7 +1723,7 @@ class vector : private container_detail::vector_alloc_holder<A>
|
|||||||
//New situation in Case A (hole_size == 0):
|
//New situation in Case A (hole_size == 0):
|
||||||
// range is moved through move assignments
|
// range is moved through move assignments
|
||||||
//
|
//
|
||||||
// first_pos last_pos old_limit
|
// first_pos last_pos limit_pos
|
||||||
// | | |
|
// | | |
|
||||||
// ____________V_______V__________________V_____________
|
// ____________V_______V__________________V_____________
|
||||||
//| prefix' | | | range |suffix'|raw_mem ~
|
//| prefix' | | | range |suffix'|raw_mem ~
|
||||||
@@ -1735,7 +1735,7 @@ class vector : private container_detail::vector_alloc_holder<A>
|
|||||||
//New situation in Case B (hole_size > 0):
|
//New situation in Case B (hole_size > 0):
|
||||||
// range is moved through uninitialized moves
|
// range is moved through uninitialized moves
|
||||||
//
|
//
|
||||||
// first_pos last_pos old_limit
|
// first_pos last_pos limit_pos
|
||||||
// | | |
|
// | | |
|
||||||
// ____________V_______V__________________V________________
|
// ____________V_______V__________________V________________
|
||||||
//| prefix' | | | [hole] | range |
|
//| prefix' | | | [hole] | range |
|
||||||
@@ -1746,31 +1746,33 @@ class vector : private container_detail::vector_alloc_holder<A>
|
|||||||
//New situation in Case C (hole_size == 0):
|
//New situation in Case C (hole_size == 0):
|
||||||
// range is moved through move assignments and uninitialized moves
|
// range is moved through move assignments and uninitialized moves
|
||||||
//
|
//
|
||||||
// first_pos last_pos old_limit
|
// first_pos last_pos limit_pos
|
||||||
// | | |
|
// | | |
|
||||||
// ____________V_______V__________________V___
|
// ____________V_______V__________________V___
|
||||||
//| prefix' | | | range |
|
//| prefix' | | | range |
|
||||||
//|___________________________________|___^___|
|
//|___________________________________|___^___|
|
||||||
// | |
|
// | |
|
||||||
// |_>_>_>_>_>_>_>_>_>_>_>^
|
// |_>_>_>_>_>_>_>_>_>_>_>^
|
||||||
size_type priv_insert_ordered_at_shift_range(size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
|
size_type priv_insert_ordered_at_shift_range
|
||||||
|
(size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(first_pos <= last_pos);
|
BOOST_ASSERT(first_pos <= last_pos);
|
||||||
BOOST_ASSERT(last_pos <= limit_pos);
|
BOOST_ASSERT(last_pos <= limit_pos);
|
||||||
//
|
//
|
||||||
T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
|
T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
|
||||||
|
T* const first_ptr = begin_ptr + first_pos;
|
||||||
|
T* const last_ptr = begin_ptr + last_pos;
|
||||||
|
|
||||||
size_type hole_size = 0;
|
size_type hole_size = 0;
|
||||||
//Case A:
|
//Case A:
|
||||||
if((last_pos + shift_count) <= limit_pos){
|
if((last_pos + shift_count) <= limit_pos){
|
||||||
//All move assigned
|
//All move assigned
|
||||||
boost::move_backward(begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + last_pos + shift_count);
|
boost::move_backward(first_ptr, last_ptr, last_ptr + shift_count);
|
||||||
}
|
}
|
||||||
//Case B:
|
//Case B:
|
||||||
else if((first_pos + shift_count) >= limit_pos){
|
else if((first_pos + shift_count) >= limit_pos){
|
||||||
//All uninitialized_moved
|
//All uninitialized_moved
|
||||||
::boost::container::uninitialized_move_alloc
|
::boost::container::uninitialized_move_alloc(this->alloc(), first_ptr, last_ptr, first_ptr + shift_count);
|
||||||
(this->alloc(), begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + first_pos + shift_count);
|
|
||||||
hole_size = last_pos + shift_count - limit_pos;
|
hole_size = last_pos + shift_count - limit_pos;
|
||||||
}
|
}
|
||||||
//Case C:
|
//Case C:
|
||||||
@@ -1778,10 +1780,9 @@ class vector : private container_detail::vector_alloc_holder<A>
|
|||||||
//Some uninitialized_moved
|
//Some uninitialized_moved
|
||||||
T* const limit_ptr = begin_ptr + limit_pos;
|
T* const limit_ptr = begin_ptr + limit_pos;
|
||||||
T* const boundary_ptr = limit_ptr - shift_count;
|
T* const boundary_ptr = limit_ptr - shift_count;
|
||||||
::boost::container::uninitialized_move_alloc
|
::boost::container::uninitialized_move_alloc(this->alloc(), boundary_ptr, last_ptr, limit_ptr);
|
||||||
(this->alloc(), boundary_ptr, begin_ptr + last_pos, limit_ptr);
|
|
||||||
//The rest is move assigned
|
//The rest is move assigned
|
||||||
boost::move_backward(begin_ptr + first_pos, boundary_ptr, limit_ptr);
|
boost::move_backward(first_ptr, boundary_ptr, limit_ptr);
|
||||||
}
|
}
|
||||||
return hole_size;
|
return hole_size;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user