Hello,

this patch moves _M_size in std::list to a place where it should be easier (no offsetof) to access from an iterator (it doesn't matter when you access it from the main std::list object). It does not take advantage of it yet, that can be done at any time, whereas the layout will soon be fixed. This triggered one of the issues listed in PR 63345 (casting to a node* even for the sentinel), which I am fixing here.

Bootstrap+testsuite on x86_64-linux-gnu.

2014-10-13  Marc Glisse  <marc.gli...@inria.fr>

        PR libstdc++/61347
        PR libstdc++/63345
        * include/bits/list.tcc (_List_base::_M_clear()): Delay cast so it
        isn't done for the sentinel.
        * include/bits/stl_list.h (_List_base::_M_size): Move...
        (_List_base::_List_impl::_M_node): ... here.
        (_List_base::_M_get_size(), _List_base::_M_set_size(size_t),
        _List_base::_M_inc_size(size_t), _List_base::_M_dec_size(size_t),
        _List_base::_M_node_count): Adapt to the move.
        * 23_containers/list/requirements/dr438/assign_neg.cc: Update
        line number.
        * 23_containers/list/requirements/dr438/constructor_1_neg.cc: Likewise.
        * 23_containers/list/requirements/dr438/constructor_2_neg.cc: Likewise.
        * 23_containers/list/requirements/dr438/insert_neg.cc: Likewise.


--
Marc Glisse
Index: include/bits/list.tcc
===================================================================
--- include/bits/list.tcc       (revision 216116)
+++ include/bits/list.tcc       (working copy)
@@ -59,25 +59,25 @@
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
   template<typename _Tp, typename _Alloc>
     void
     _List_base<_Tp, _Alloc>::
     _M_clear() _GLIBCXX_NOEXCEPT
     {
       typedef _List_node<_Tp>  _Node;
-      _Node* __cur = static_cast<_Node*>(_M_impl._M_node._M_next);
+      __detail::_List_node_base* __cur = _M_impl._M_node._M_next;
       while (__cur != &_M_impl._M_node)
        {
-         _Node* __tmp = __cur;
-         __cur = static_cast<_Node*>(__cur->_M_next);
+         _Node* __tmp = static_cast<_Node*>(__cur);
+         __cur = __tmp->_M_next;
 #if __cplusplus >= 201103L
          _M_get_Node_allocator().destroy(__tmp);
 #else
          _M_get_Tp_allocator().destroy(std::__addressof(__tmp->_M_data));
 #endif
          _M_put_node(__tmp);
        }
     }
 
 #if __cplusplus >= 201103L
Index: include/bits/stl_list.h
===================================================================
--- include/bits/stl_list.h     (revision 216116)
+++ include/bits/stl_list.h     (working copy)
@@ -325,57 +325,59 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          {
            __first = __first->_M_next;
            ++__n;
          }
        return __n;
       }
 
       struct _List_impl
       : public _Node_alloc_type
       {
+#if _GLIBCXX_USE_CXX11_ABI
+       _List_node<size_t> _M_node;
+#else
        __detail::_List_node_base _M_node;
+#endif
 
        _List_impl()
        : _Node_alloc_type(), _M_node()
        { }
 
        _List_impl(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPT
        : _Node_alloc_type(__a), _M_node()
        { }
 
 #if __cplusplus >= 201103L
        _List_impl(_Node_alloc_type&& __a) _GLIBCXX_NOEXCEPT
        : _Node_alloc_type(std::move(__a)), _M_node()
        { }
 #endif
       };
 
       _List_impl _M_impl;
 
 #if _GLIBCXX_USE_CXX11_ABI
-      size_t    _M_size;
-
-      size_t _M_get_size() const { return _M_size; }
+      size_t _M_get_size() const { return _M_impl._M_node._M_data; }
 
-      void _M_set_size(size_t __n) { _M_size = __n; }
+      void _M_set_size(size_t __n) { _M_impl._M_node._M_data = __n; }
 
-      void _M_inc_size(size_t __n) { _M_size += __n; }
+      void _M_inc_size(size_t __n) { _M_impl._M_node._M_data += __n; }
 
-      void _M_dec_size(size_t __n) { _M_size -= __n; }
+      void _M_dec_size(size_t __n) { _M_impl._M_node._M_data -= __n; }
 
       size_t
       _M_distance(const __detail::_List_node_base* __first,
                  const __detail::_List_node_base* __last) const
       { return _S_distance(__first, __last); }
 
       // return the stored size
-      size_t _M_node_count() const { return _M_size; }
+      size_t _M_node_count() const { return _M_impl._M_node._M_data; }
 #else
       // dummy implementations used when the size is not stored
       size_t _M_get_size() const { return 0; }
       void _M_set_size(size_t) { }
       void _M_inc_size(size_t) { }
       void _M_dec_size(size_t) { }
       size_t _M_distance(const void*, const void*) const { return 0; }
 
       // count the number of nodes
       size_t _M_node_count() const
Index: testsuite/23_containers/list/requirements/dr438/assign_neg.cc
===================================================================
--- testsuite/23_containers/list/requirements/dr438/assign_neg.cc       
(revision 216116)
+++ testsuite/23_containers/list/requirements/dr438/assign_neg.cc       
(working copy)
@@ -11,21 +11,21 @@
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 
 // You should have received a copy of the GNU General Public License along
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1728 }
+// { dg-error "no matching" "" { target *-*-* } 1730 }
 
 #include <list>
 
 struct A
 {
   explicit A(int) { }
 };
 
 void f()
 {
Index: testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
===================================================================
--- testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc        
(revision 216116)
+++ testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc        
(working copy)
@@ -11,19 +11,19 @@
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 
 // You should have received a copy of the GNU General Public License along
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1680 }
+// { dg-error "no matching" "" { target *-*-* } 1682 }
 
 #include <list>
 
 void f()
 {
   typedef std::list<std::list<int> > list_type;
   list_type l(10, 1);
 }
Index: testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
===================================================================
--- testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc        
(revision 216116)
+++ testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc        
(working copy)
@@ -11,20 +11,20 @@
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 
 // You should have received a copy of the GNU General Public License along
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1680 }
+// { dg-error "no matching" "" { target *-*-* } 1682 }
 
 #include <list>
 #include <utility>
 
 void f()
 {
   typedef std::list<std::list<std::pair<char, char> > > list_type;
   list_type l('a', 'b');
 }
Index: testsuite/23_containers/list/requirements/dr438/insert_neg.cc
===================================================================
--- testsuite/23_containers/list/requirements/dr438/insert_neg.cc       
(revision 216116)
+++ testsuite/23_containers/list/requirements/dr438/insert_neg.cc       
(working copy)
@@ -11,21 +11,21 @@
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 
 // You should have received a copy of the GNU General Public License along
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1680 }
+// { dg-error "no matching" "" { target *-*-* } 1682 }
 
 #include <list>
 
 struct A
 {
   explicit A(int) { }
 };
 
 void f()
 {

Reply via email to