On Thu, 21 May 2026 at 22:20 +0200, François Dumont wrote:
Hi

Following your remark Jonathan regarding how iterators are invalidated in vector I reviewed the std::__debug::vector implementation.

Can you remind me where I said that? I remember discussing it for
inplace_vector::assign (2025-11-03 in the thread about
__debug::inplace_vector).

I don't remember the comment you're referring to, so I don't know what
I said :-)

I'll do something similar on std::__debug::inplace_vector.

    libstdc++: [_GLIBCXX_DEBUG] Enhance __gnu_debug::vector iterator invalidation

    Rework the way std::__debug::vector's iterators are being invalidated. Use a guard     approach which on destructor invalidates iterators based on the state of the container.

    Moreover update invalidation policy in following vector methods:
    - operator=(initializer_list)
    - assign(Iterator, Iterator)
    - assign(size_t, const _Tp&)
    - assign(initializer_list)

    Current behavior to invalidate all iterators unconditionally is preserved only if     _GLIBCXX_DEBUG_PEDANTIC is defined. Otherwise if a reallocation occurs all iterators     are invaliidated else only iterators after the new container size are invalidated.

    libstdc++-v3/ChangeLog:

            * include/debug/assertions.h [_GLIBCXX_DEBUG_STD_C]: New macro.
            * include/debug/vector (_Safe_vector<_Tp, _Allocator>): Update template parameter.
            (_Safe_vector::_M_requires_reallocation): Remove.
            (_SafeVectorGuard): New.
            [_GLIBCXX_DEBUG_PEDANTIC](_SafeVectorPedanticGuard): New.
            (_SafeVectorInsertGuard): New.
            (vector): Adapt methods to use new guard type.
            * testsuite/23_containers/vector/cons/destructible_debug_neg.cc: Adapt error line
            number.
            * testsuite/23_containers/vector/debug/initializer_list.cc: New test case.             * testsuite/23_containers/vector/debug/initializer_list_pedantic.cc: New test case.

Partially tested on x86_64 w/o _GLIBCXX_DEBUG mode.

Ok to commit once tests completed ?

https://forge.sourceware.org/gcc/gcc-TEST/pulls/159

François



diff --git a/libstdc++-v3/include/debug/assertions.h 
b/libstdc++-v3/include/debug/assertions.h
index c4993dc8596..768a7f05228 100644
--- a/libstdc++-v3/include/debug/assertions.h
+++ b/libstdc++-v3/include/debug/assertions.h
@@ -31,6 +31,12 @@

#include <bits/c++config.h>

+#ifdef _GLIBCXX_DEBUG
+# define _GLIBCXX_DEBUG_STD_C ::std::_GLIBCXX_STD_C
+#else
+# define _GLIBCXX_DEBUG_STD_C ::std
+#endif
+
#ifndef _GLIBCXX_DEBUG
// Verify that [_First, _Last) forms a non-empty iterator range.
# define __glibcxx_requires_non_empty_range(_First,_Last)       \
diff --git a/libstdc++-v3/include/debug/vector 
b/libstdc++-v3/include/debug/vector
index 61e5ff78a7a..1e1a971036e 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -51,11 +51,12 @@ namespace __gnu_debug
   * detecting code which relies on non-portable implementation details of
   * the libstdc++ reallocation policy.
   */
-  template<typename _SafeSequence,
-          typename _BaseSequence>
+  template<class _Tp, typename _Allocator>
    class _Safe_vector
    {
-      typedef typename _BaseSequence::size_type size_type;
+      typedef std::__debug::vector<_Tp, _Allocator> _SafeSequence;
+      typedef _GLIBCXX_DEBUG_STD_C::vector<_Tp, _Allocator> _StdVector;
+      typedef typename _StdVector::size_type size_type;

      _GLIBCXX20_CONSTEXPR
      const _SafeSequence&
@@ -103,10 +104,6 @@ namespace __gnu_debug

      size_type _M_guaranteed_capacity;

-      bool
-      _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
-      { return __elements > _M_seq().capacity(); }
-
      _GLIBCXX20_CONSTEXPR
      void
      _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
@@ -115,6 +112,66 @@ namespace __gnu_debug
          _M_guaranteed_capacity = _M_seq().size();
      }
    };
+
+  template<class _Tp, typename _Allocator>
+    class _SafeVectorGuard
+    {
+      typedef std::__debug::vector<_Tp, _Allocator> _SafeVector;
+      typedef _GLIBCXX_DEBUG_STD_C::vector<_Tp, _Allocator> _StdVector;
+      typedef typename _StdVector::size_type size_type;
+
+      _SafeVector& _M_vect;
+      size_type _M_capacity, _M_size;
+
+    public:
+      bool _M_active;
+
+      _GLIBCXX20_CONSTEXPR
+      _SafeVectorGuard(_SafeVector& __vector);
+
+      _GLIBCXX20_CONSTEXPR
+      ~_SafeVectorGuard();
+    };
+
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+  template<class _Tp, typename _Allocator>
+    class _SafeVectorPedanticGuard
+    {
+      typedef std::__debug::vector<_Tp, _Allocator> _SafeVector;
+      _SafeVector& _M_vect;
+
+    public:
+      bool _M_active;
+
+      _GLIBCXX20_CONSTEXPR
+      _SafeVectorPedanticGuard(_SafeVector& __vector);
+
+      _GLIBCXX20_CONSTEXPR
+      ~_SafeVectorPedanticGuard();
+    };
+#endif
+
+  template<class _Tp, typename _Allocator>
+    class _SafeVectorInsertGuard
+    {
+      typedef std::__debug::vector<_Tp, _Allocator> _SafeVector;
+      typedef _GLIBCXX_DEBUG_STD_C::vector<_Tp, _Allocator> _StdVector;
+      typedef typename _StdVector::size_type size_type;
+      typedef typename _StdVector::difference_type difference_type;
+
+      _SafeVector& _M_vect;
+      size_type _M_capacity;
+      difference_type _M_offset;
+
+    public:
+      bool _M_active;
+
+      _GLIBCXX20_CONSTEXPR
+      _SafeVectorInsertGuard(_SafeVector& __vector, difference_type __offset);
+
+      _GLIBCXX20_CONSTEXPR
+      ~_SafeVectorInsertGuard();
+    };
}

All the guard types above need comments explaining what they do. When
should you use each one? How are they different from each other?

How do we deviate from the standard when not in pedantic mode?

I'm unclear what they actually do, and how that corresponds to the
standard.

_SafeVectorGuard invalidates all iterators if the size increased to
greater than capacity. That's used by resize and emplace_back and
push_back, right? And if the size was reduced, invalidate iterators to
the erased elements. This must not be used for reserve, because it
would not invalidate all iterators on reallocation, because the size
would not change.

_SafeVectorPedanticGuard invalidates all iterators unconditionally,
which is what the standard says to do for assign.

_SafeVectorInsertGuard seems to be almost the same as _SafeVectorGuard
but using an arbitrary position for the "invalidates all after pos"
instead of only invalidating at the end.

Would it be more clear to have _ResizeGuard, _AssignGuard (which
changes behaviour for pedantic vs non-pedantic), and _InsertGuard?


namespace std _GLIBCXX_VISIBILITY(default)
@@ -128,14 +185,33 @@ namespace __debug
    : public __gnu_debug::_Safe_container<
        vector<_Tp, _Allocator>, _Allocator, __gnu_debug::_Safe_sequence>,
      public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
-      public __gnu_debug::_Safe_vector<
-       vector<_Tp, _Allocator>,
-       _GLIBCXX_STD_C::vector<_Tp, _Allocator> >
+      public __gnu_debug::_Safe_vector<_Tp, _Allocator>
    {
      typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator>             _Base;
      typedef __gnu_debug::_Safe_container<
        vector, _Allocator, __gnu_debug::_Safe_sequence>     _Safe;
-      typedef __gnu_debug::_Safe_vector<vector, _Base>           _Safe_vector;
+      typedef __gnu_debug::_Safe_vector<_Tp, _Allocator> _Safe_vector;
+
+      typedef __gnu_debug::_SafeVectorGuard<_Tp, _Allocator> _Guard;
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+      typedef __gnu_debug::_SafeVectorPedanticGuard<_Tp, _Allocator>
+       _MaybePedanticGuard;
+#else
+      typedef _Guard _MaybePedanticGuard;

This name seems focused on the detail of how we decide which type to
use, not what it actually does. And _SafeVectorGuard is also "maybe
pedantic" because its destructor changes behaviour for pedantic mode.

Would _AssignGuard be a better name? That reflects where it's actually
used.

+#endif
+      typedef __gnu_debug::_SafeVectorInsertGuard<_Tp, _Allocator>
+       _InsertGuard;
+
+      template<typename _Tp2, typename _Alloc2>
+       friend class ::__gnu_debug::_SafeVectorGuard;
+
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+      template<typename _Tp2, typename _Alloc2>
+       friend class ::__gnu_debug::_SafeVectorPedanticGuard;
+#endif
+
+      template<typename _Tp2, typename _Alloc2>
+       friend class ::__gnu_debug::_SafeVectorInsertGuard;

      typedef typename _Base::iterator          _Base_iterator;
      typedef typename _Base::const_iterator    _Base_const_iterator;
@@ -276,12 +352,9 @@ namespace __debug
      vector&
      operator=(initializer_list<value_type> __l)
      {
+       _MaybePedanticGuard __guard(*this);
        _Base::operator=(__l);
-       if (!std::__is_constant_evaluated())
-         {
-           this->_M_invalidate_all();
-           this->_M_update_guaranteed_capacity();
-         }
+       __guard._M_active = true;
        return *this;
      }
#endif
@@ -303,26 +376,23 @@ namespace __debug
          typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
          __glibcxx_check_valid_range2(__first, __last, __dist);

+         _MaybePedanticGuard __guard(*this);
          if (__dist.second >= __gnu_debug::__dp_sign)
            _Base::assign(__gnu_debug::__unsafe(__first),
                          __gnu_debug::__unsafe(__last));
          else
            _Base::assign(__first, __last);

-         this->_M_invalidate_all();
-         this->_M_update_guaranteed_capacity();
+         __guard._M_active = true;
        }

      _GLIBCXX20_CONSTEXPR
      void
      assign(size_type __n, const _Tp& __u)
      {
+       _MaybePedanticGuard __guard(*this);
        _Base::assign(__n, __u);
-       if (!std::__is_constant_evaluated())
-         {
-           this->_M_invalidate_all();
-           this->_M_update_guaranteed_capacity();
-         }
+       __guard._M_active = true;
      }

#if __cplusplus >= 201103L
@@ -330,12 +400,9 @@ namespace __debug
      void
      assign(initializer_list<value_type> __l)
      {
+       _MaybePedanticGuard __guard(*this);
        _Base::assign(__l);
-       if (!std::__is_constant_evaluated())
-         {
-           this->_M_invalidate_all();
-           this->_M_update_guaranteed_capacity();
-         }
+       __guard._M_active = true;
      }
#endif

@@ -428,13 +495,9 @@ namespace __debug
        if (std::__is_constant_evaluated())
          return _Base::resize(__sz);

-       bool __realloc = this->_M_requires_reallocation(__sz);
-       if (__sz < this->size())
-         this->_M_invalidate_after_nth(__sz);
+       _Guard __guard(*this);
        _Base::resize(__sz);
-       if (__realloc)
-         this->_M_invalidate_all();
-       this->_M_update_guaranteed_capacity();
+       __guard._M_active = true;
      }

      _GLIBCXX20_CONSTEXPR
@@ -444,25 +507,17 @@ namespace __debug
        if (std::__is_constant_evaluated())
          return _Base::resize(__sz, __c);

-       bool __realloc = this->_M_requires_reallocation(__sz);
-       if (__sz < this->size())
-         this->_M_invalidate_after_nth(__sz);
+       _Guard __guard(*this);
        _Base::resize(__sz, __c);
-       if (__realloc)
-         this->_M_invalidate_all();
-       this->_M_update_guaranteed_capacity();
+       __guard._M_active = true;
      }
#else
      void
      resize(size_type __sz, _Tp __c = _Tp())
      {
-       bool __realloc = this->_M_requires_reallocation(__sz);
-       if (__sz < this->size())
-         this->_M_invalidate_after_nth(__sz);
+       _Guard __guard(*this);
        _Base::resize(__sz, __c);
-       if (__realloc)
-         this->_M_invalidate_all();
-       this->_M_update_guaranteed_capacity();
+       __guard._M_active = true;
      }
#endif

@@ -506,7 +561,7 @@ namespace __debug
        if (std::__is_constant_evaluated())
          return _Base::reserve(__n);

-       bool __realloc = this->_M_requires_reallocation(__n);
+       bool __realloc = __n > capacity();
        _Base::reserve(__n);
        if (__n > this->_M_guaranteed_capacity)
          this->_M_guaranteed_capacity = __n;
@@ -583,11 +638,9 @@ namespace __debug
        if (std::__is_constant_evaluated())
          return _Base::push_back(__x);

-       bool __realloc = this->_M_requires_reallocation(this->size() + 1);
+       _Guard __guard(*this);
        _Base::push_back(__x);
-       if (__realloc)
-         this->_M_invalidate_all();
-       this->_M_update_guaranteed_capacity();
+       __guard._M_active = true;
      }

#if __cplusplus >= 201103L
@@ -610,11 +663,9 @@ namespace __debug
          if (std::__is_constant_evaluated())
            return _Base::emplace_back(std::forward<_Args>(__args)...);

-         bool __realloc = this->_M_requires_reallocation(this->size() + 1);
+         _Guard __guard(*this);
          _Base::emplace_back(std::forward<_Args>(__args)...);
-         if (__realloc)
-           this->_M_invalidate_all();
-         this->_M_update_guaranteed_capacity();
+         __guard._M_active = true;
#if __cplusplus > 201402L
          return back();
#endif
@@ -645,15 +696,14 @@ namespace __debug
                            this);

          __glibcxx_check_insert(__position);
-         bool __realloc = this->_M_requires_reallocation(this->size() + 1);
+         _Base_iterator __res;
+         {
            difference_type __offset = __position.base() - _Base::cbegin();
-         _Base_iterator __res = _Base::emplace(__position.base(),
+           _InsertGuard __guard(*this, __offset);
+           __res = _Base::emplace(__position.base(),
                                   std::forward<_Args>(__args)...);
-         if (__realloc)
-           this->_M_invalidate_all();
-         else
-           this->_M_invalidate_after_nth(__offset);
-         this->_M_update_guaranteed_capacity();
+           __guard._M_active = true;
+         }
          return { __res, this };
        }
#endif
@@ -670,14 +720,13 @@ namespace __debug
          return iterator(_Base::insert(__position.base(), __x), this);

        __glibcxx_check_insert(__position);
-       bool __realloc = this->_M_requires_reallocation(this->size() + 1);
+       _Base_iterator __res;
+       {
          difference_type __offset = __position.base() - _Base::begin();
-       _Base_iterator __res = _Base::insert(__position.base(), __x);
-       if (__realloc)
-         this->_M_invalidate_all();
-       else
-         this->_M_invalidate_after_nth(__offset);
-       this->_M_update_guaranteed_capacity();
+         _InsertGuard __guard(*this, __offset);
+         __res = _Base::insert(__position.base(), __x);
+         __guard._M_active = true;
+       }
        return iterator(__res, this);
      }

@@ -704,14 +753,13 @@ namespace __debug
          return iterator(_Base::insert(__position.base(), __n, __x), this);

        __glibcxx_check_insert(__position);
-       bool __realloc = this->_M_requires_reallocation(this->size() + __n);
+       _Base_iterator __res;
+       {
          difference_type __offset = __position.base() - _Base::cbegin();
-       _Base_iterator __res = _Base::insert(__position.base(), __n, __x);
-       if (__realloc)
-         this->_M_invalidate_all();
-       else
-         this->_M_invalidate_after_nth(__offset);
-       this->_M_update_guaranteed_capacity();
+         _InsertGuard __guard(*this, __offset);
+         __res = _Base::insert(__position.base(), __n, __x);
+         __guard._M_active = true;
+       }
        return { __res, this };
      }
#else
@@ -719,14 +767,10 @@ namespace __debug
      insert(iterator __position, size_type __n, const _Tp& __x)
      {
        __glibcxx_check_insert(__position);
-       bool __realloc = this->_M_requires_reallocation(this->size() + __n);
        difference_type __offset = __position.base() - _Base::begin();
+       _InsertGuard __guard(*this, __offset);
        _Base::insert(__position.base(), __n, __x);
-       if (__realloc)
-         this->_M_invalidate_all();
-       else
-         this->_M_invalidate_after_nth(__offset);
-       this->_M_update_guaranteed_capacity();
+       __guard._M_active = true;
      }
#endif

@@ -746,12 +790,10 @@ namespace __debug
          typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
          __glibcxx_check_insert_range(__position, __first, __last, __dist);

-         /* Hard to guess if invalidation will occur, because __last
-            - __first can't be calculated in all cases, so we just
-            punt here by checking if it did occur. */
-         _Base_iterator __old_begin = _M_base().begin();
-         difference_type __offset = __position.base() - _Base::cbegin();
          _Base_iterator __res;
+         {
+           difference_type __offset = __position.base() - _Base::cbegin();
+           _InsertGuard __guard(*this, __offset);
            if (__dist.second >= __gnu_debug::__dp_sign)
              __res = _Base::insert(__position.base(),
                                    __gnu_debug::__unsafe(__first),
@@ -759,11 +801,8 @@ namespace __debug
            else
              __res = _Base::insert(__position.base(), __first, __last);

-         if (_M_base().begin() != __old_begin)
-           this->_M_invalidate_all();
-         else
-           this->_M_invalidate_after_nth(__offset);
-         this->_M_update_guaranteed_capacity();
+           __guard._M_active = true;
+         }
          return { __res, this };
        }
#else
@@ -775,22 +814,15 @@ namespace __debug
          typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
          __glibcxx_check_insert_range(__position, __first, __last, __dist);

-         /* Hard to guess if invalidation will occur, because __last
-            - __first can't be calculated in all cases, so we just
-            punt here by checking if it did occur. */
-         _Base_iterator __old_begin = _M_base().begin();
          difference_type __offset = __position.base() - _Base::begin();
+         _InsertGuard __guard(*this, __offset);
          if (__dist.second >= __gnu_debug::__dp_sign)
            _Base::insert(__position.base(), __gnu_debug::__unsafe(__first),
                                             __gnu_debug::__unsafe(__last));
          else
            _Base::insert(__position.base(), __first, __last);

-         if (_M_base().begin() != __old_begin)
-           this->_M_invalidate_all();
-         else
-           this->_M_invalidate_after_nth(__offset);
-         this->_M_update_guaranteed_capacity();
+         __guard._M_active = true;
        }
#endif

@@ -876,30 +908,20 @@ namespace __debug
        constexpr void
        assign_range(_Rg&& __rg)
        {
-         auto __old_capacity = _Base::capacity();
-         auto __old_size = _Base::size();
+         _Guard __guard(*this);
          _Base::assign_range(__rg);
-         if (!std::__is_constant_evaluated())
-           {
-             if (_Base::capacity() != __old_capacity)
-               this->_M_invalidate_all();
-             else if (_Base::size() < __old_size)
-               this->_M_invalidate_after_nth(_Base::size());
-             this->_M_update_guaranteed_capacity();
-           }
+         __guard._M_active = true;
        }

      template<__detail::__container_compatible_range<_Tp> _Rg>
        constexpr iterator
        insert_range(const_iterator __pos, _Rg&& __rg)
        {
-         auto __old_capacity = _Base::capacity();
-         auto __res = _Base::insert_range(__pos.base(), __rg);
-         if (!std::__is_constant_evaluated())
+         _Base_iterator __res;
          {
-             if (_Base::capacity() != __old_capacity)
-               this->_M_invalidate_all();
-             this->_M_update_guaranteed_capacity();
+           _Guard __guard(*this);
+           __res = _Base::insert_range(__pos.base(), __rg);
+           __guard._M_active = true;
          }
          return iterator(__res, this);
        }
@@ -908,14 +930,9 @@ namespace __debug
        constexpr void
        append_range(_Rg&& __rg)
        {
-         auto __old_capacity = _Base::capacity();
+         _Guard __guard(*this);
          _Base::append_range(__rg);
-         if (!std::__is_constant_evaluated())
-           {
-             if (_Base::capacity() != __old_capacity)
-               this->_M_invalidate_all();
-             this->_M_update_guaranteed_capacity();
-           }
+         __guard._M_active = true;
        }
#endif

@@ -1057,6 +1074,84 @@ _GLIBCXX_END_NAMESPACE_VERSION

namespace __gnu_debug
{
+  template<class _Tp, typename _Allocator>
+    _GLIBCXX20_CONSTEXPR
+    _SafeVectorGuard<_Tp, _Allocator>::_SafeVectorGuard(
+      std::__debug::vector<_Tp, _Allocator>& __vector)
+    : _M_vect(__vector)
+    , _M_capacity(__vector.capacity())
+    , _M_size(__vector.size())
+    , _M_active(false)
+    { }
+
+  template<class _Tp, typename _Allocator>
+    _GLIBCXX20_CONSTEXPR
+    _SafeVectorGuard<_Tp, _Allocator>::~_SafeVectorGuard()
+    {
+      if (!std::__is_constant_evaluated() && _M_active)
+       {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+         if (_M_vect.size() > _M_capacity)
+#else
+         if (_M_vect.capacity() != _M_capacity)
+#endif

I don't understand this condition. What difference does it make, and
why do we want it?

For resize and emplace_back/push_back the two conditions are
equivalent, right? _M_vect.capacity() would not change (i.e.
reallocation would not occur) unless v.size() == v.capacity(),
and in that case v.size() would become greater than capacity.

When are these different?

+           _M_vect._M_invalidate_all();
+         else if (_M_vect.size() < _M_size)
+           _M_vect._M_invalidate_after_nth(_M_vect.size());
+
+         _M_vect._M_update_guaranteed_capacity();
+       }
+    }
+
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+  template<class _Tp, typename _Allocator>
+    _GLIBCXX20_CONSTEXPR
+    _SafeVectorPedanticGuard<_Tp, _Allocator>::_SafeVectorPedanticGuard(
+      std::__debug::vector<_Tp, _Allocator>& __vector)
+    : _M_vect(__vector), _M_active(false)
+    { }
+
+  template<class _Tp, typename _Allocator>
+    _GLIBCXX20_CONSTEXPR
+    _SafeVectorPedanticGuard<_Tp, _Allocator>::~_SafeVectorPedanticGuard()
+    {
+      if (!std::__is_constant_evaluated() && _M_active)
+       {
+         _M_vect._M_invalidate_all();
+         _M_vect._M_update_guaranteed_capacity();
+       }
+    }
+#endif
+
+  template<class _Tp, typename _Allocator>
+    _GLIBCXX20_CONSTEXPR
+    _SafeVectorInsertGuard<_Tp, _Allocator>::_SafeVectorInsertGuard(
+      std::__debug::vector<_Tp, _Allocator>& __vector, difference_type 
__offset)
+    : _M_vect(__vector)
+    , _M_capacity(__vector.capacity())
+    , _M_offset(__offset)
+    , _M_active(false)
+    { }
+
+  template<class _Tp, typename _Allocator>
+    _GLIBCXX20_CONSTEXPR
+    _SafeVectorInsertGuard<_Tp, _Allocator>::~_SafeVectorInsertGuard()
+    {
+      if (!std::__is_constant_evaluated() && _M_active)
+       {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+         if (_M_vect.size() > _M_capacity)
+#else
+         if (_M_vect.capacity() != _M_capacity)
+#endif

Same question here.

+           _M_vect._M_invalidate_all();
+         else
+           _M_vect._M_invalidate_after_nth(_M_offset);
+
+         _M_vect._M_update_guaranteed_capacity();
+       }
+    }
+
  template<typename _Tp, typename _Alloc>
    struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> >
    : std::__true_type
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc 
b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
index 2c9abcdbb91..0a29c0432e6 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
@@ -47,4 +47,4 @@ test02()
// { dg-error "PrivateDtor.* is private" "" { target *-*-* } 0 }

// In Debug Mode the "required from here" errors come from <debug/vector>
-// { dg-error "required from here" "" { target *-*-* } 182 }
+// { dg-error "required from here" "" { target *-*-* } 258 }
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/debug/initializer_list.cc 
b/libstdc++-v3/testsuite/23_containers/vector/debug/initializer_list.cc
new file mode 100644
index 00000000000..318f6b98de9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/initializer_list.cc
@@ -0,0 +1,26 @@
+// { dg-do compile { target c++11 } }
+
+#include <debug/vector>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  __gnu_debug::vector<int> v = { 0, 1, 2, 3, 4, 5 };
+
+  auto it1 = v.begin() + 1;
+  auto it4 = v.begin() + 4;
+
+  VERIFY( !it1._M_singular() );
+  VERIFY( !it4._M_singular() );
+
+  v = { 10, 11, 12, 13 };
+
+  VERIFY( !it1._M_singular() );
+  VERIFY( it4._M_singular() );
+}
+
+int main()
+{
+  test01();
+}
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/debug/initializer_list_pedantic.cc
 
b/libstdc++-v3/testsuite/23_containers/vector/debug/initializer_list_pedantic.cc
new file mode 100644
index 00000000000..c8b3af25bd1
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/23_containers/vector/debug/initializer_list_pedantic.cc
@@ -0,0 +1,27 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" }
+
+#include <debug/vector>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  __gnu_debug::vector<int> v = { 0, 1, 2, 3, 4, 5 };
+
+  auto it1 = v.begin() + 1;
+  auto it4 = v.begin() + 4;
+
+  VERIFY( !it1._M_singular() );
+  VERIFY( !it4._M_singular() );
+
+  v = { 10, 11, 12, 13 };
+
+  VERIFY( it1._M_singular() );
+  VERIFY( it4._M_singular() );
+}
+
+int main()
+{
+  test01();
+}

Reply via email to