Hi

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

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();
+    };
 }
 
 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;
+#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
+           _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
+           _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