C++11 allocator support for std::list.
authorJonathan Wakely <jwakely@redhat.com>
Wed, 17 Jun 2015 20:36:42 +0000 (21:36 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 17 Jun 2015 20:36:42 +0000 (21:36 +0100)
PR libstdc++/55409
* include/bits/list.tcc (_List_base::_M_clear()): Use allocator traits.
(list::list(const list&)): Use allocator propagation trait. Use
_M_assign_dispatch to copy elements.
* include/bits/stl_list.h (_List_node): Use __aligned_membuf in C++11.
(_List_node::_M_valptr()): Add accessor for stored value.
(_List_iterator, _List_const_iterator, _List_base): Use _M_valptr().
(_List_base, list): Use allocator traits.
(_List_base::_M_get_Tp_allocator, _List_base::get_allocator): Remove.
(_List_base::_M_move_nodes): New function.
(_List_base(_List_base&&)): Use _M_move_nodes.
(_List_base(_List_base&&, _Node_alloc_type&&)): New constructor.
(list::_M_create_node, list::_M_erase, list::max_size): Use allocator
traits.
(list(size_type)): Add allocator parameter.
(list(const list&)): Use allocator propagation trait.
(list(const list&, const allocator_type&)): New constructor.
(list(list&&, const allocator_type&)): Likewise.
(list::operator=(list&&), list::swap(list&)): Use allocator
propagation traits.
(list::_M_move_assign): New functions.
* include/debug/list: Add allocator-extended constructors.
* include/profile/list: Likewise.
* python/libstdcxx/v6/printers.py (get_value_from_list_node): New
function to get value from _List_node.
(StdListPrinter): Use get_value_from_list_node.
* testsuite/23_containers/list/allocator/copy.cc: New.
* testsuite/23_containers/list/allocator/copy_assign.cc: New.
* testsuite/23_containers/list/allocator/minimal.cc: New.
* testsuite/23_containers/list/allocator/move.cc: New.
* testsuite/23_containers/list/allocator/move_assign.cc: New.
* testsuite/23_containers/list/allocator/noexcept.cc: New.
* testsuite/23_containers/list/allocator/swap.cc: New.
* testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
Adjust dg-prune-output line number.
* testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc:
Likewise.
* testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
Likewise.

From-SVN: r224580

16 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/list.tcc
libstdc++-v3/include/bits/stl_list.h
libstdc++-v3/include/debug/list
libstdc++-v3/include/profile/list
libstdc++-v3/python/libstdcxx/v6/printers.py
libstdc++-v3/testsuite/23_containers/list/allocator/copy.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/allocator/copy_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/allocator/minimal.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/allocator/move_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/allocator/noexcept.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/allocator/swap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc

index ea0a60d4b9e00a4e55b6b7cdace96a5c82858088..345bf945ded75b4f102fc67ffc11ad6f25e4a383 100644 (file)
@@ -1,5 +1,45 @@
 2015-06-17  Jonathan Wakely  <jwakely@redhat.com>
 
+       PR libstdc++/55409
+       * include/bits/list.tcc (_List_base::_M_clear()): Use allocator traits.
+       (list::list(const list&)): Use allocator propagation trait. Use
+       _M_assign_dispatch to copy elements.
+       * include/bits/stl_list.h (_List_node): Use __aligned_membuf in C++11.
+       (_List_node::_M_valptr()): Add accessor for stored value.
+       (_List_iterator, _List_const_iterator, _List_base): Use _M_valptr().
+       (_List_base, list): Use allocator traits.
+       (_List_base::_M_get_Tp_allocator, _List_base::get_allocator): Remove.
+       (_List_base::_M_move_nodes): New function.
+       (_List_base(_List_base&&)): Use _M_move_nodes.
+       (_List_base(_List_base&&, _Node_alloc_type&&)): New constructor.
+       (list::_M_create_node, list::_M_erase, list::max_size): Use allocator
+       traits.
+       (list(size_type)): Add allocator parameter.
+       (list(const list&)): Use allocator propagation trait.
+       (list(const list&, const allocator_type&)): New constructor.
+       (list(list&&, const allocator_type&)): Likewise.
+       (list::operator=(list&&), list::swap(list&)): Use allocator
+       propagation traits.
+       (list::_M_move_assign): New functions.
+       * include/debug/list: Add allocator-extended constructors.
+       * include/profile/list: Likewise.
+       * python/libstdcxx/v6/printers.py (get_value_from_list_node): New
+       function to get value from _List_node.
+       (StdListPrinter): Use get_value_from_list_node.
+       * testsuite/23_containers/list/allocator/copy.cc: New.
+       * testsuite/23_containers/list/allocator/copy_assign.cc: New.
+       * testsuite/23_containers/list/allocator/minimal.cc: New.
+       * testsuite/23_containers/list/allocator/move.cc: New.
+       * testsuite/23_containers/list/allocator/move_assign.cc: New.
+       * testsuite/23_containers/list/allocator/noexcept.cc: New.
+       * testsuite/23_containers/list/allocator/swap.cc: New.
+       * testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
+       Adjust dg-prune-output line number.
+       * testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc:
+       Likewise.
+       * testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
+       Likewise.
+
        * include/bits/forward_list.h
        (_Fwd_list_base(const _Node_alloc_type&)): Change parameter to
        rvalue-reference.
index 95193c19a2447a3cf415cdf7cc50cfb97b663c60..714d9b522a783e7a7df2a13ffd14dd4b62537de9 100644 (file)
@@ -71,10 +71,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        {
          _Node* __tmp = static_cast<_Node*>(__cur);
          __cur = __tmp->_M_next;
+         _Tp* __val = __tmp->_M_valptr();
 #if __cplusplus >= 201103L
-         _M_get_Node_allocator().destroy(__tmp);
+         _Node_alloc_traits::destroy(_M_get_Node_allocator(), __val);
 #else
-         _M_get_Tp_allocator().destroy(std::__addressof(__tmp->_M_data));
+         _Tp_alloc_type(_M_get_Node_allocator()).destroy(__val);
 #endif
          _M_put_node(__tmp);
        }
@@ -267,17 +268,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     {
       if (this != std::__addressof(__x))
        {
-         iterator __first1 = begin();
-         iterator __last1 = end();
-         const_iterator __first2 = __x.begin();
-         const_iterator __last2 = __x.end();
-         for (; __first1 != __last1 && __first2 != __last2;
-              ++__first1, ++__first2)
-           *__first1 = *__first2;
-         if (__first2 == __last2)
-           erase(__first1, __last1);
-         else
-           insert(__last1, __first2, __last2);
+#if __cplusplus >= 201103L
+         if (_Node_alloc_traits::_S_propagate_on_copy_assign())
+           {
+              auto& __this_alloc = this->_M_get_Node_allocator();
+              auto& __that_alloc = __x._M_get_Node_allocator();
+              if (!_Node_alloc_traits::_S_always_equal()
+                 && __this_alloc != __that_alloc)
+               {
+                 // replacement allocator cannot free existing storage
+                 clear();
+               }
+             std::__alloc_on_copy(__this_alloc, __that_alloc);
+            }
+#endif
+         _M_assign_dispatch(__x.begin(), __x.end(), __false_type());
        }
       return *this;
     }
index a498de5d3a65e1558f01496a0d6688c52b792a08..6a729fb992e6f04ff39497b12cbe0c0142c72405 100644 (file)
 #define _STL_LIST_H 1
 
 #include <bits/concept_check.h>
+#include <ext/alloc_traits.h>
 #if __cplusplus >= 201103L
 #include <initializer_list>
+#include <bits/allocated_ptr.h>
+#include <ext/aligned_buffer.h>
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -105,14 +108,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   template<typename _Tp>
     struct _List_node : public __detail::_List_node_base
     {
-      ///< User's data.
-      _Tp _M_data;
-
 #if __cplusplus >= 201103L
-      template<typename... _Args>
-        _List_node(_Args&&... __args)
-       : __detail::_List_node_base(), _M_data(std::forward<_Args>(__args)...) 
-        { }
+      __gnu_cxx::__aligned_membuf<_Tp> _M_storage;
+      _Tp*       _M_valptr()       { return _M_storage._M_ptr(); }
+      _Tp const* _M_valptr() const { return _M_storage._M_ptr(); }
+#else
+      _Tp _M_data;
+      _Tp*       _M_valptr()       { return std::__addressof(_M_data); }
+      _Tp const* _M_valptr() const { return std::__addressof(_M_data); }
 #endif
     };
 
@@ -144,14 +147,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _M_const_cast() const _GLIBCXX_NOEXCEPT
       { return *this; }
 
-      // Must downcast from _List_node_base to _List_node to get to _M_data.
+      // Must downcast from _List_node_base to _List_node to get to value.
       reference
       operator*() const _GLIBCXX_NOEXCEPT
-      { return static_cast<_Node*>(_M_node)->_M_data; }
+      { return *static_cast<_Node*>(_M_node)->_M_valptr(); }
 
       pointer
       operator->() const _GLIBCXX_NOEXCEPT
-      { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
+      { return static_cast<_Node*>(_M_node)->_M_valptr(); }
 
       _Self&
       operator++() _GLIBCXX_NOEXCEPT
@@ -228,15 +231,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _M_const_cast() const _GLIBCXX_NOEXCEPT
       { return iterator(const_cast<__detail::_List_node_base*>(_M_node)); }
 
-      // Must downcast from List_node_base to _List_node to get to
-      // _M_data.
+      // Must downcast from List_node_base to _List_node to get to value.
       reference
       operator*() const _GLIBCXX_NOEXCEPT
-      { return static_cast<_Node*>(_M_node)->_M_data; }
+      { return *static_cast<_Node*>(_M_node)->_M_valptr(); }
 
       pointer
       operator->() const _GLIBCXX_NOEXCEPT
-      { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
+      { return static_cast<_Node*>(_M_node)->_M_valptr(); }
 
       _Self&
       operator++() _GLIBCXX_NOEXCEPT
@@ -298,23 +300,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
     class _List_base
     {
     protected:
-      // NOTA BENE
-      // The stored instance is not actually of "allocator_type"'s
-      // type.  Instead we rebind the type to
-      // Allocator<List_node<Tp>>, which according to [20.1.5]/4
-      // should probably be the same.  List_node<Tp> is not the same
-      // size as Tp (it's two pointers larger), and specializations on
-      // Tp may go unused because List_node<Tp> is being bound
-      // instead.
-      //
-      // We put this to the test in the constructors and in
-      // get_allocator, where we use conversions between
-      // allocator_type and _Node_alloc_type. The conversion is
-      // required by table 32 in [20.1.5].
-      typedef typename _Alloc::template rebind<_List_node<_Tp> >::other
-        _Node_alloc_type;
-
-      typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+       rebind<_Tp>::other                              _Tp_alloc_type;
+      typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type>        _Tp_alloc_traits;
+      typedef typename _Tp_alloc_traits::template
+       rebind<_List_node<_Tp> >::other _Node_alloc_type;
+      typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
 
       static size_t
       _S_distance(const __detail::_List_node_base* __first,
@@ -338,7 +329,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        __detail::_List_node_base _M_node;
 #endif
 
-       _List_impl()
+       _List_impl() _GLIBCXX_NOEXCEPT
        : _Node_alloc_type(), _M_node()
        { }
 
@@ -347,7 +338,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        { }
 
 #if __cplusplus >= 201103L
-       _List_impl(_Node_alloc_type&& __a) _GLIBCXX_NOEXCEPT
+       _List_impl(_Node_alloc_type&& __a) noexcept
        : _Node_alloc_type(std::move(__a)), _M_node()
        { }
 #endif
@@ -356,13 +347,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       _List_impl _M_impl;
 
 #if _GLIBCXX_USE_CXX11_ABI
-      size_t _M_get_size() const { return _M_impl._M_node._M_data; }
+      size_t _M_get_size() const { return *_M_impl._M_node._M_valptr(); }
 
-      void _M_set_size(size_t __n) { _M_impl._M_node._M_data = __n; }
+      void _M_set_size(size_t __n) { *_M_impl._M_node._M_valptr() = __n; }
 
-      void _M_inc_size(size_t __n) { _M_impl._M_node._M_data += __n; }
+      void _M_inc_size(size_t __n) { *_M_impl._M_node._M_valptr() += __n; }
 
-      void _M_dec_size(size_t __n) { _M_impl._M_node._M_data -= __n; }
+      void _M_dec_size(size_t __n) { *_M_impl._M_node._M_valptr() -= __n; }
 
       size_t
       _M_distance(const __detail::_List_node_base* __first,
@@ -370,7 +361,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       { return _S_distance(__first, __last); }
 
       // return the stored size
-      size_t _M_node_count() const { return _M_impl._M_node._M_data; }
+      size_t _M_node_count() const { return *_M_impl._M_node._M_valptr(); }
 #else
       // dummy implementations used when the size is not stored
       size_t _M_get_size() const { return 0; }
@@ -387,32 +378,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       }
 #endif
 
-      _List_node<_Tp>*
+      typename _Node_alloc_traits::pointer
       _M_get_node()
-      { return _M_impl._Node_alloc_type::allocate(1); }
+      { return _Node_alloc_traits::allocate(_M_impl, 1); }
 
       void
-      _M_put_node(_List_node<_Tp>* __p) _GLIBCXX_NOEXCEPT
-      { _M_impl._Node_alloc_type::deallocate(__p, 1); }
+      _M_put_node(typename _Node_alloc_traits::pointer __p) _GLIBCXX_NOEXCEPT
+      { _Node_alloc_traits::deallocate(_M_impl, __p, 1); }
 
   public:
       typedef _Alloc allocator_type;
 
       _Node_alloc_type&
       _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
-      { return *static_cast<_Node_alloc_type*>(&_M_impl); }
+      { return _M_impl; }
 
       const _Node_alloc_type&
       _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
-      { return *static_cast<const _Node_alloc_type*>(&_M_impl); }
-
-      _Tp_alloc_type
-      _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT
-      { return _Tp_alloc_type(_M_get_Node_allocator()); }
-
-      allocator_type
-      get_allocator() const _GLIBCXX_NOEXCEPT
-      { return allocator_type(_M_get_Node_allocator()); }
+      { return _M_impl; }
 
       _List_base()
       : _M_impl()
@@ -425,6 +408,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 #if __cplusplus >= 201103L
       _List_base(_List_base&& __x) noexcept
       : _M_impl(std::move(__x._M_get_Node_allocator()))
+      { _M_move_nodes(std::move(__x)); }
+
+      _List_base(_List_base&& __x, _Node_alloc_type&& __a)
+      : _M_impl(std::move(__a))
+      {
+       if (__x._M_get_Node_allocator() == _M_get_Node_allocator())
+         _M_move_nodes(std::move(__x));
+       else
+         _M_init(); // Caller must move individual elements.
+      }
+
+      void
+      _M_move_nodes(_List_base&& __x)
       {
        auto* const __xnode = std::__addressof(__x._M_impl._M_node);
        if (__xnode->_M_next == __xnode)
@@ -513,16 +509,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
       typedef _List_base<_Tp, _Alloc>                    _Base;
       typedef typename _Base::_Tp_alloc_type            _Tp_alloc_type;
+      typedef typename _Base::_Tp_alloc_traits          _Tp_alloc_traits;
       typedef typename _Base::_Node_alloc_type          _Node_alloc_type;
+      typedef typename _Base::_Node_alloc_traits        _Node_alloc_traits;
 
     public:
       typedef _Tp                                        value_type;
-      typedef typename _Tp_alloc_type::pointer           pointer;
-      typedef typename _Tp_alloc_type::const_pointer     const_pointer;
-      typedef typename _Tp_alloc_type::reference         reference;
-      typedef typename _Tp_alloc_type::const_reference   const_reference;
-      typedef _List_iterator<_Tp>                        iterator;
-      typedef _List_const_iterator<_Tp>                  const_iterator;
+      typedef typename _Tp_alloc_traits::pointer        pointer;
+      typedef typename _Tp_alloc_traits::const_pointer  const_pointer;
+      typedef typename _Tp_alloc_traits::reference      reference;
+      typedef typename _Tp_alloc_traits::const_reference const_reference;
+      typedef _List_iterator<_Tp>                       iterator;
+      typedef _List_const_iterator<_Tp>                         const_iterator;
       typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
       typedef std::reverse_iterator<iterator>            reverse_iterator;
       typedef size_t                                     size_type;
@@ -537,7 +535,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       using _Base::_M_impl;
       using _Base::_M_put_node;
       using _Base::_M_get_node;
-      using _Base::_M_get_Tp_allocator;
       using _Base::_M_get_Node_allocator;
 
       /**
@@ -553,8 +550,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        _Node* __p = this->_M_get_node();
        __try
          {
-           _M_get_Tp_allocator().construct
-             (std::__addressof(__p->_M_data), __x);
+           _Tp_alloc_type __alloc(_M_get_Node_allocator());
+           __alloc.construct(__p->_M_valptr(), __x);
          }
        __catch(...)
          {
@@ -568,17 +565,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
         _Node*
         _M_create_node(_Args&&... __args)
        {
-         _Node* __p = this->_M_get_node();
-         __try
-           {
-             _M_get_Node_allocator().construct(__p,
-                                               std::forward<_Args>(__args)...);
-           }
-         __catch(...)
-           {
-             _M_put_node(__p);
-             __throw_exception_again;
-           }
+         auto __p = this->_M_get_node();
+         auto& __alloc = _M_get_Node_allocator();
+         __allocated_ptr<_Node_alloc_type> __guard{__alloc, __p};
+         _Node_alloc_traits::construct(__alloc, __p->_M_valptr(),
+                                       std::forward<_Args>(__args)...);
+         __guard = nullptr;
          return __p;
        }
 #endif
@@ -608,13 +600,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       /**
        *  @brief  Creates a %list with default constructed elements.
        *  @param  __n  The number of elements to initially create.
+       *  @param  __a  An allocator object.
        *
        *  This constructor fills the %list with @a __n default
        *  constructed elements.
        */
       explicit
-      list(size_type __n)
-      : _Base()
+      list(size_type __n, const allocator_type& __a = allocator_type())
+      : _Base(_Node_alloc_type(__a))
       { _M_default_initialize(__n); }
 
       /**
@@ -653,7 +646,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        *  by @a __x.
        */
       list(const list& __x)
-      : _Base(__x._M_get_Node_allocator())
+      : _Base(_Node_alloc_traits::
+             _S_select_on_copy(__x._M_get_Node_allocator()))
       { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); }
 
 #if __cplusplus >= 201103L
@@ -679,6 +673,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
            const allocator_type& __a = allocator_type())
       : _Base(_Node_alloc_type(__a))
       { _M_initialize_dispatch(__l.begin(), __l.end(), __false_type()); }
+
+      list(const list& __x, const allocator_type& __a)
+      : _Base(_Node_alloc_type(__a))
+      { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); }
+
+      list(list&& __x, const allocator_type& __a)
+      noexcept(_Node_alloc_traits::_S_always_equal())
+      : _Base(std::move(__x), _Node_alloc_type(__a))
+      {
+       // If __x is not empty it means its allocator is not equal to __a,
+       // so we need to move from each element individually.
+       insert(begin(), std::__make_move_if_noexcept_iterator(__x.begin()),
+                       std::__make_move_if_noexcept_iterator(__x.end()));
+      }
 #endif
 
       /**
@@ -738,11 +746,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        */
       list&
       operator=(list&& __x)
+      noexcept(_Node_alloc_traits::_S_nothrow_move())
       {
-       // NB: DR 1204.
-       // NB: DR 675.
-       this->clear();
-       this->swap(__x);
+       constexpr bool __move_storage =
+          _Node_alloc_traits::_S_propagate_on_move_assign()
+          || _Node_alloc_traits::_S_always_equal();
+        _M_move_assign(std::move(__x),
+                       integral_constant<bool, __move_storage>());
        return *this;
       }
 
@@ -820,7 +830,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       /// Get a copy of the memory allocation object.
       allocator_type
       get_allocator() const _GLIBCXX_NOEXCEPT
-      { return _Base::get_allocator(); }
+      { return allocator_type(_Base::_M_get_Node_allocator()); }
 
       // iterators
       /**
@@ -949,7 +959,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       /**  Returns the size() of the largest possible %list.  */
       size_type
       max_size() const _GLIBCXX_NOEXCEPT
-      { return _M_get_Node_allocator().max_size(); }
+      { return _Node_alloc_traits::max_size(_M_get_Node_allocator()); }
 
 #if __cplusplus >= 201103L
       /**
@@ -1342,18 +1352,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        */
       void
       swap(list& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Node_alloc_traits::_S_nothrow_swap())
+#endif
       {
-       __detail::_List_node_base::swap(this->_M_impl._M_node, 
-                                       __x._M_impl._M_node);
+       __detail::_List_node_base::swap(this->_M_impl._M_node,
+                                       __x._M_impl._M_node);
 
        size_t __xsize = __x._M_get_size();
        __x._M_set_size(this->_M_get_size());
        this->_M_set_size(__xsize);
 
-       // _GLIBCXX_RESOLVE_LIB_DEFECTS
-       // 431. Swapping containers with unequal allocators.
-       std::__alloc_swap<typename _Base::_Node_alloc_type>::
-         _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator());
+       _Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(),
+                                       __x._M_get_Node_allocator());
       }
 
       /**
@@ -1774,10 +1785,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
         __position._M_node->_M_unhook();
         _Node* __n = static_cast<_Node*>(__position._M_node);
 #if __cplusplus >= 201103L
-        _M_get_Node_allocator().destroy(__n);
+       _Node_alloc_traits::destroy(_M_get_Node_allocator(), __n->_M_valptr());
 #else
-       _M_get_Tp_allocator().destroy(std::__addressof(__n->_M_data));
+       _Tp_alloc_type(_M_get_Node_allocator()).destroy(__n->_M_valptr());
 #endif
+
         _M_put_node(__n);
       }
 
@@ -1793,6 +1805,40 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       // Used to implement resize.
       const_iterator
       _M_resize_pos(size_type& __new_size) const;
+
+#if __cplusplus >= 201103L
+      void
+      _M_move_assign(list&& __x, true_type) noexcept
+      {
+       this->_M_clear();
+       if (__x.empty())
+         this->_M_init();
+       else
+         {
+           this->_M_impl._M_node._M_next = __x._M_impl._M_node._M_next;
+           this->_M_impl._M_node._M_next->_M_prev = &this->_M_impl._M_node;
+           this->_M_impl._M_node._M_prev = __x._M_impl._M_node._M_prev;
+           this->_M_impl._M_node._M_prev->_M_next = &this->_M_impl._M_node;
+           this->_M_set_size(__x._M_get_size());
+           __x._M_init();
+         }
+        std::__alloc_on_move(this->_M_get_Node_allocator(),
+                             __x._M_get_Node_allocator());
+      }
+
+      void
+      _M_move_assign(list&& __x, false_type)
+      {
+       if (__x._M_get_Node_allocator() == this->_M_get_Node_allocator())
+          _M_move_assign(std::move(__x), true_type{});
+        else
+         // The rvalue's allocator cannot be moved, or is not equal,
+         // so we need to individually move each element.
+         _M_assign_dispatch(std::__make_move_if_noexcept_iterator(__x.begin()),
+                            std::__make_move_if_noexcept_iterator(__x.end()),
+                            __false_type{});
+      }
+#endif
     };
 _GLIBCXX_END_NAMESPACE_CXX11
 
@@ -1903,7 +1949,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       ++__beyond;
       bool __whole = __first == __beyond;
       if (__builtin_constant_p (__whole) && __whole)
-       return static_cast<const _Sentinel*>(__last._M_node)->_M_data;
+       return *static_cast<const _Sentinel*>(__last._M_node)->_M_valptr();
 
       ptrdiff_t __n = 0;
       while (__first != __last)
index 9f4c9c0a9741794c09007b8b917d511107c8a80b..1562946311bf09b95811de2f7e128fe47a0834cc 100644 (file)
@@ -94,6 +94,12 @@ namespace __debug
       : _Base(__l, __a) { }
 
       ~list() = default;
+
+      list(const list& __x, const allocator_type& __a)
+      : _Base(__x, __a) { }
+
+      list(list&& __x, const allocator_type& __a)
+      : _Base(std::move(__x), __a) { }
 #endif
 
       explicit
@@ -102,8 +108,8 @@ namespace __debug
 
 #if __cplusplus >= 201103L
       explicit
-      list(size_type __n)
-      : _Base(__n) { }
+      list(size_type __n, const allocator_type& __a = allocator_type())
+      : _Base(__n, __a) { }
 
       list(size_type __n, const _Tp& __value,
           const _Allocator& __a = _Allocator())
index e21244c015b823b08a854b8c56860cbfcf4267be..b5943ee6dfc5dc025b448d2bcd0cc88380f3b9ca 100644 (file)
@@ -145,6 +145,12 @@ namespace __profile
       list(initializer_list<value_type> __l,
           const allocator_type& __a = allocator_type())
       : _Base(__l, __a) { }
+
+      list(const list& __x, const allocator_type& __a)
+      : _Base(__x, __a) { }
+
+      list(list&& __x, const allocator_type& __a)
+      : _Base(std::move(__x), __a) { }
 #endif
 
       explicit
@@ -153,8 +159,8 @@ namespace __profile
 
 #if __cplusplus >= 201103L
       explicit
-      list(size_type __n)
-      : _Base(__n) { }
+      list(size_type __n, const allocator_type& __a = allocator_type())
+      : _Base(__n, __a) { }
 
       list(size_type __n, const _Tp& __value,
           const _Allocator& __a = _Allocator())
index 2b6e4096ae4001e4c7c72b03a8bd74f2b71ed649..2d167863ad3f2b3cca723806b9e1dc4ae4da6a0b 100644 (file)
@@ -128,6 +128,22 @@ class UniquePointerPrinter:
         return ('std::unique_ptr<%s> containing %s' % (str(v.type.target()),
                                                        str(v)))
 
+def get_value_from_list_node(node):
+    """Returns the value held in an _List_node<_Val>"""
+    try:
+        member = node.type.fields()[1].name
+        if member == '_M_data':
+            # C++03 implementation, node contains the value as a member
+            return node['_M_data']
+        elif member == '_M_storage':
+            # C++11 implementation, node stores value in __aligned_membuf
+            p = node['_M_storage']['_M_storage'].address
+            p = p.cast(node.type.template_argument(0).pointer())
+            return p.dereference()
+    except:
+        pass
+    raise ValueError("Unsupported implementation for %s" % str(node.type))
+
 class StdListPrinter:
     "Print a std::list"
 
@@ -148,7 +164,8 @@ class StdListPrinter:
             self.base = elt['_M_next']
             count = self.count
             self.count = self.count + 1
-            return ('[%d]' % count, elt['_M_data'])
+            val = get_value_from_list_node(elt)
+            return ('[%d]' % count, val)
 
     def __init__(self, typename, val):
         self.typename = typename
@@ -174,7 +191,8 @@ class StdListIteratorPrinter:
     def to_string(self):
         nodetype = find_type(self.val.type, '_Node')
         nodetype = nodetype.strip_typedefs().pointer()
-        return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
+        node = self.val['_M_node'].cast(nodetype).dereference()
+        return get_value_from_list_node(node)
 
 class StdSlistPrinter:
     "Print a __gnu_cxx::slist"
@@ -440,7 +458,7 @@ def get_value_from_Rb_tree_node(node):
             # C++03 implementation, node contains the value as a member
             return node['_M_value_field']
         elif member == '_M_storage':
-            # C++11 implementation, node stores value in __aligned_buffer
+            # C++11 implementation, node stores value in __aligned_membuf
             p = node['_M_storage']['_M_storage'].address
             p = p.cast(node.type.template_argument(0).pointer())
             return p.dereference()
diff --git a/libstdc++-v3/testsuite/23_containers/list/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/list/allocator/copy.cc
new file mode 100644 (file)
index 0000000..8346dee
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+
+#include <list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(0 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/list/allocator/copy_assign.cc
new file mode 100644 (file)
index 0000000..1a2aa0a
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+
+#include <list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(alloc_type(2));
+  v2.push_front(T());
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(alloc_type(2));
+  v2.push_front(T());
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/list/allocator/minimal.cc
new file mode 100644 (file)
index 0000000..f9dbdac
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+
+#include <list>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+bool operator==(const T& l, const T& r) { return l.i == r.i; }
+bool operator<(const T& l, const T& r) { return l.i < r.i; }
+
+using __gnu_test::SimpleAllocator;
+
+template class std::list<T, SimpleAllocator<T>>;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef SimpleAllocator<T> alloc_type;
+  typedef std::allocator_traits<alloc_type> traits_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v(alloc_type{});
+  v.push_front(T());
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/list/allocator/move.cc
new file mode 100644 (file)
index 0000000..c43c190
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+
+#include <list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { T() };
+  auto it = v1.begin();
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { T() };
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/list/allocator/move_assign.cc
new file mode 100644 (file)
index 0000000..5bf1b34
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+
+#include <list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(alloc_type(2));
+  v2.push_front(T());
+  v2 = std::move(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  auto it = v1.begin();
+  test_type v2(alloc_type(2));
+  v2.push_front(T());
+  v2 = std::move(v1);
+  VERIFY(0 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+  VERIFY( it == v2.begin() );
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/list/allocator/noexcept.cc
new file mode 100644 (file)
index 0000000..4a84fce
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+
+#include <list>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+namespace __gnu_test
+{
+  template<typename U>
+    inline void
+    swap(propagating_allocator<U, true>& l, propagating_allocator<U, true>& r)
+    noexcept(false)
+    { }
+}
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  typedef std::allocator<T> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1;
+  test_type v2;
+  // this is a GNU extension for std::allocator
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test02()
+{
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test03()
+{
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" );
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/list/allocator/swap.cc
new file mode 100644 (file)
index 0000000..2ba08fd
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// 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-options "-std=gnu++11" }
+
+#include <list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<T, false>&,
+           const propagating_allocator<T, false>&)
+{
+  return true;
+}
+
+bool
+operator!=(const propagating_allocator<T, false>&,
+           const propagating_allocator<T, false>&)
+{
+  return false;
+}
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(alloc_type(2));
+  v2.push_front(T());
+  std::swap(v1, v2);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+  // swap back so assertions in uneq_allocator::deallocate don't fail
+  std::swap(v1, v2);
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(alloc_type(2));
+  v2.push_front(T());
+  std::swap(v1, v2);
+  VERIFY(2 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
index 0a60dd78e6d43016563227529944e649de2fd679..84c74734806d22257e710243d068e9f5c86a2341 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-prune-output 1730 }
+// { dg-prune-output 1741 }
 
 #include <list>
 
index 8de8b1ad0adf49432ebbb249f5e020f5354c62f8..947029c043ff30b2d8c1fe367fb49e79315cc542 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-prune-output 1682 }
+// { dg-prune-output 1693 }
 
 #include <list>
 
index c927735ff8dabb87516a15aa367c13674f3b4fcb..54e89328ce0cb0c1b4f3bcfcb64974b30bbdb13f 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-prune-output 1682 }
+// { dg-prune-output 1693 }
 
 #include <list>