$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r80514 - in trunk/boost/container: . detail
From: igaztanaga_at_[hidden]
Date: 2012-09-13 14:55:00
Author: igaztanaga
Date: 2012-09-13 14:54:58 EDT (Thu, 13 Sep 2012)
New Revision: 80514
URL: http://svn.boost.org/trac/boost/changeset/80514
Log:
Corrected strict aliasing error in multiallocation_chain
Text files modified: 
   trunk/boost/container/detail/adaptive_node_pool_impl.hpp |     3 -                                       
   trunk/boost/container/detail/multiallocation_chain.hpp   |    53 ++++++++++++++++++++++++++------------- 
   trunk/boost/container/detail/node_alloc_holder.hpp       |     3 -                                       
   trunk/boost/container/stable_vector.hpp                  |     7 +---                                    
   trunk/boost/container/vector.hpp                         |    21 ++++++++-------                         
   5 files changed, 50 insertions(+), 37 deletions(-)
Modified: trunk/boost/container/detail/adaptive_node_pool_impl.hpp
==============================================================================
--- trunk/boost/container/detail/adaptive_node_pool_impl.hpp	(original)
+++ trunk/boost/container/detail/adaptive_node_pool_impl.hpp	2012-09-13 14:54:58 EDT (Thu, 13 Sep 2012)
@@ -348,8 +348,7 @@
    {
       block_iterator block_it(m_block_multiset.end());
       while(n--){
-         void *pElem = container_detail::to_raw_pointer(chain.front());
-         chain.pop_front();
+         void *pElem = container_detail::to_raw_pointer(chain.pop_front());
          priv_invariants();
          block_info_t *block_info = this->priv_block_from_node(pElem);
          BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
Modified: trunk/boost/container/detail/multiallocation_chain.hpp
==============================================================================
--- trunk/boost/container/detail/multiallocation_chain.hpp	(original)
+++ trunk/boost/container/detail/multiallocation_chain.hpp	2012-09-13 14:54:58 EDT (Thu, 13 Sep 2012)
@@ -45,14 +45,30 @@
                     > slist_impl_t;
    slist_impl_t slist_impl_;
 
-   static node & to_node(VoidPointer p)
-   {  return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
+   typedef typename boost::intrusive::pointer_traits
+      <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)
 
    public:
 
-
    typedef VoidPointer  void_pointer;
    typedef typename slist_impl_t::iterator iterator;
    typedef typename slist_impl_t::size_type size_type;
@@ -94,19 +110,21 @@
    {  slist_impl_.clear(); }
 
    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)
-   {  return slist_impl_.push_front(to_node(m));   }
+   {  return slist_impl_.push_front(build_node(m));  }
 
    void push_back(void_pointer m)
-   {  return slist_impl_.push_back(to_node(m));   }
-
-   void pop_front()
-   {  return slist_impl_.pop_front();   }
+   {  return slist_impl_.push_back(build_node(m));   }
 
-   void *front()
-   {  return &*slist_impl_.begin();   }
+   void_pointer pop_front()
+   {
+      node & n = slist_impl_.front();
+      void_pointer ret = destroy_node(n);
+      slist_impl_.pop_front();
+      return ret;
+   }
 
    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);   }
@@ -118,10 +136,12 @@
    {  slist_impl_.splice_after(after_this, x.slist_impl_);   }
 
    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)
-   {  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)
    {  slist_impl_.swap(x.slist_impl_);   }
@@ -203,11 +223,8 @@
    void incorporate_after(iterator after_this, pointer begin, pointer before_end, size_type n)
    {  holder_.incorporate_after(after_this.base(), begin, before_end, n);  }
 
-   void pop_front()
-   {  holder_.pop_front();  }
-
-   pointer front()
-   {  return cast(holder_.front());   }
+   pointer pop_front()
+   {  return cast(holder_.pop_front());  }
 
    bool empty() const
    {  return holder_.empty(); }
Modified: trunk/boost/container/detail/node_alloc_holder.hpp
==============================================================================
--- trunk/boost/container/detail/node_alloc_holder.hpp	(original)
+++ trunk/boost/container/detail/node_alloc_holder.hpp	2012-09-13 14:54:58 EDT (Thu, 13 Sep 2012)
@@ -247,8 +247,7 @@
          Node *p = 0;
          BOOST_TRY{
                for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
-               p = container_detail::to_raw_pointer(mem.front());
-               mem.pop_front();
+               p = container_detail::to_raw_pointer(mem.pop_front());
                //This can throw
                constructed = 0;
                boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
Modified: trunk/boost/container/stable_vector.hpp
==============================================================================
--- trunk/boost/container/stable_vector.hpp	(original)
+++ trunk/boost/container/stable_vector.hpp	2012-09-13 14:54:58 EDT (Thu, 13 Sep 2012)
@@ -589,9 +589,7 @@
             ::value>::type * = 0)
    {
       while(!holder.empty()){
-         const node_ptr n = holder.front();
-         holder.pop_front();
-         this->deallocate_one(n);
+         this->deallocate_one(holder.pop_front());
       }
    }
 
@@ -1697,8 +1695,7 @@
                               , node_ptr_traits::static_cast_from(pool_first_ref)
                               , node_ptr_traits::static_cast_from(pool_last_ref)
                               , internal_data.pool_size);
-      node_ptr ret = holder.front();
-      holder.pop_front();
+      node_ptr ret = holder.pop_front();
       --this->internal_data.pool_size;
       if(!internal_data.pool_size){
          pool_first_ref = pool_last_ref = node_ptr();
Modified: trunk/boost/container/vector.hpp
==============================================================================
--- trunk/boost/container/vector.hpp	(original)
+++ trunk/boost/container/vector.hpp	2012-09-13 14:54:58 EDT (Thu, 13 Sep 2012)
@@ -1723,7 +1723,7 @@
    //New situation in Case A (hole_size == 0):
    // range is moved through move assignments
    //
-   //       first_pos   last_pos         old_limit
+   //       first_pos   last_pos         limit_pos
    //             |       |                  | 
    // ____________V_______V__________________V_____________
    //|   prefix'  |       |  | range |suffix'|raw_mem      ~
@@ -1735,7 +1735,7 @@
    //New situation in Case B (hole_size > 0):
    // range is moved through uninitialized moves
    //
-   //       first_pos   last_pos         old_limit
+   //       first_pos   last_pos         limit_pos
    //             |       |                  | 
    // ____________V_______V__________________V________________
    //|    prefix' |       |                  | [hole] | range |
@@ -1746,31 +1746,33 @@
    //New situation in Case C (hole_size == 0):
    // range is moved through move assignments and uninitialized moves
    //
-   //       first_pos   last_pos         old_limit
+   //       first_pos   last_pos         limit_pos
    //             |       |                  | 
    // ____________V_______V__________________V___
    //|   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(last_pos <= limit_pos);
       //
       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;
       //Case A:
       if((last_pos + shift_count) <= limit_pos){
          //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:
       else if((first_pos + shift_count) >= limit_pos){
          //All uninitialized_moved
-         ::boost::container::uninitialized_move_alloc
-            (this->alloc(), begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + first_pos + shift_count);
+         ::boost::container::uninitialized_move_alloc(this->alloc(), first_ptr, last_ptr, first_ptr + shift_count);
          hole_size = last_pos + shift_count - limit_pos;
       }
       //Case C:
@@ -1778,10 +1780,9 @@
          //Some uninitialized_moved
          T* const limit_ptr    = begin_ptr + limit_pos;
          T* const boundary_ptr = limit_ptr - shift_count;
-         ::boost::container::uninitialized_move_alloc
-            (this->alloc(), boundary_ptr, begin_ptr + last_pos, limit_ptr);
+         ::boost::container::uninitialized_move_alloc(this->alloc(), boundary_ptr, last_ptr, limit_ptr);
          //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;
    }