Hi

    libstdc++: [_GLIBCXX_DEBUG] Make constant evaluation compatible

    In a constant evaluation context the _GLIBCXX_DEBUG is working in a
    degradated mode where only iterators are keeping a link to their container,
    the container won't have a list of its iterators.

    In std::__debug::vector and std::__debug::inplace_vector remove all calls to     std::is_constant_evaluated and code associated to it when returning true. The
    same code is now used in both contexts.

    Issues will be reported thanks to an invalid call to a not-constexpr
    __gnu_debug::__glibcxx_fail() function.

    libstdc++-v3/ChangeLog:

            * include/debug/forward_list (_Sequence_traits<>::_S_size): Declare as C++20
            constexpr.
            * include/debug/functions.h
            (__check_valid_range<_Ite>): Remove std::__is_constant_evaluated check.             (__foreign_iterator): Declare as C++20 constexpr and add std::__is_constant_evaluated
            check.
            * include/debug/helper_functions.h (__check_singular_aux): Declare as C++22 constexpr.             (__check_singular<_Ite>(_Ite const&)): Remove std::__is_constant_evaluated check.             * include/debug/inplace_vector: Remove all calls to std::is_contant_evaluated().             * include/debug/list (_Sequence_traits<>::_S_size): Declare as C++20 constexpr.
            * include/debug/macros.h (__gnu_debug::__glibcxx_fail): New.
            (_GLIBCXX_DEBUG_VERIFY_AT_F): Add std::__is_constant_evaluated section.
            * include/debug/safe_base.h
            (_Safe_iterator_base::_M_attach_to): New.
            (_Safe_iterator_base::_M_detach_sequence): New.
            (_Safe_iterator_base(const _Safe_sequence_base*, bool): Remove
            __is_constant_evaluated check and call _M_attach_to.
            (_Safe_iterator_base(const _Safe_iterator_base&, bool)): Likewise.             (~_Safe_iterator_base()): Remove __is_constant_evaluated check and call
            _M_detach_sequence.
            (_Safe_iterator_base::_M_is_singular): New.
            (_Safe_iterator_base::_M_is_comparable): New.
            (__check_singular_aux(const _Safe_iterator_base*)): Declare as C++20 constexpr
            and call _M_is_singular.
            * include/debug/safe_container.h (_Safe_container::_M_swap_base): Declare as             C++20 constexpr and skip operation if in constant evaluation context.             (_Safe_container(_Safe_container&&, const _Alloc&, std::false_type)): Remove
            __is_constant_evaluated check.
(_Safe_container::operator=(_Safe_container<>&&)): Likewise.
            * include/debug/safe_iterator.h (_GLIBCXX_DEBUG_VERIFY_OPERANDS): Likewise.
            (_BeforeBeginHelper<>::_S_Is): Declare as C++20 constexpr.
            (_BeforeBeginHelper<>::_S_Is_Beginnest): Declare as C++20 constexpr.
            (_Sequence_traits<>::_S_size): Declare as C++20 constexpr.
            (_Safe_iterator::_Iter_base, _Safe_iterator::_Safe_base): Remove.             (_Safe_iterator(const _Safe_iterator&, _Unchecked)): Remove __is_constant_evaluated
            check.
            (_Safe_iterator(const _Safe_iterator&)): Likewise.
            (_Safe_iterator(_Safe_iterator&&)): Likewise.
            (_Safe_iterator<>::operator=(const _Safe_iterator&)): Adapt use of __is_constant_evaluated
            to avoid __scoped_lock instantiation.
(_Safe_iterator<>::operator=(_Safe_iterator&&)): Likewise.
            (_Safe_iterator<>::operator++()): Likewise.
            (_Safe_iterator<>::operator*()): Remove __is_constant_evaluated check.
            (_Safe_iterator<>::operator->()): Likewise.
            (_Safe_iterator<>::operator++(int)): Likewise.
            (_Safe_iterator<>::_M_singular()): New, C++20 constexpr.
            (_Safe_iterator<>::_M_can_compare(const _Safe_iterator_base&)): New, C++20 constexpr.             (_Safe_iterator<>::_M_attach()): Declare as C++20 constexpr, use base class
            _M_attach_sequence().
            (_Safe_iterator<>::_M_detach()): New, C++20 constexpr, use base class
            _M_detach_sequence().
            (_Safe_iterator<>::_M_dereferenceable()): Declare as C++20 constexpr.
            (_Safe_iterator<>::_M_before_dereferenceable()): Likewise.
            (_Safe_iterator<>::_M_incrementable()): Likewise.
            (_Safe_iterator<>::_M_value_initialized()): Likewise.
            (_Safe_iterator<>::_M_can_advance()): Likewise.
            (_Safe_iterator<>::_M_valid_range): Likewise.
            (_Safe_iterator<>::_M_get_sequence()): Likewise.
(_Safe_iterator<>::_M_get_distance_from_begin()): Likewise.
            (_Safe_iterator<>::_M_get_distance_to_end()): Likewise.
            (_Safe_iterator<>::_M_is_end()): Likewise.
            (_Safe_iterator<>::_M_is_before_begin()): Likewise.
            (_Safe_iterator<>::_M_is_beginnest()): Likewise.
            (_Safe_iterator<>::operator--()): Adapt use of __is_constant_evaluated to avoid
            __scoped_lock instantiation.
            (_Safe_iterator<>::operator+=(difference_type)): Likewise.
            (_Safe_iterator<>::operator-=(difference_type)): Likewise.
            (_Safe_iterator<>::operator--(int)): Declare as C++20 constexpr.
            (_Safe_iterator<>::_M_decrementable()): Likewise.
            (_Safe_iterator<>::operator[](difference_type)): Likewise.
            (operator<(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.             (operator<=(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.             (operator>(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.             (operator>=(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.             (operator+(const _Safe_iterator<>&, difference_type)): Likewise.             (operator+(difference_type, const _Safe_iterator<>&)): Likewise.             (operator-(const _Safe_iterator<>&, difference_type)): Likewise.             (operator-(difference_type, const _Safe_iterator<>&)): Likewise.
            (__valid_range<>): Likewise.
            (__can_advance<>): Likewise.
            * include/debug/safe_iterator.tcc: Adapt method with C++20 constexpr declaration.
            * include/debug/safe_local_iterator.h
            (_Safe_local_iterator<>::_Iter_base, _Safe_local_iterator<>::_Safe_base):
            Remove.
            (_Safe_local_iterator<>::_M_singular): New.
            (_Safe_local_iterator<>::_M_can_compare(const _Safe_iterator_base&)): New.             (_Safe_local_iterator<>::_M_attach): Declare C++20 constexpr, use base class
            _M_attach_to.
            * include/debug/safe_sequence.h
            (_Safe_sequence<>::_M_invalidate_if_impl): New.
            (_Safe_sequence<>::_M_invalidate_if): Call later if not __is_constant_evaluated.
            * include/debug/safe_sequence.tcc: Rename _M_invalidate_if into
            _M_invalidate_if_impl and not C++20 constexpr.
            * include/debug/safe_unordered_base.h: Remove useless this->.
            * include/debug/vector: Adapt, remove all use of std::__is_constant_evaluated.
            * src/c++11/debug.cc
            (_Safe_sequence_base::_M_detach_singular()): Use new _M_is_singular.
(_Safe_sequence_base::_M_detach_single(_Safe_iterator_base* it)):
            Do not check if it equals _M_iterators if it was equal to _M_const_iterators.
            (_Safe_iterator_base::_M_singular): Use _M_is_singular.
(_Safe_iterator_base::_M_singular)[_GLIBCXX_INLINE_VERSION]: Remove.
            (_Safe_iterator_base::_M_can_compare): Use _M_is_comparable.
(_Safe_iterator_base::_M_can_compare)[_GLIBCXX_INLINE_VERSION]: Remove.
(_Safe_unordered_container_base::_M_detach_local_single(_Safe_iterator_base*)):
            Do not check if it equals _M_local_iterators if it was equal to
            _M_const_local_iterators.

PR: https://forge.sourceware.org/gcc/gcc-TEST/pulls/136

I noticed on the PR that some bot is running tests and spotted some regressions that are now fixed.

I run some tests locally and requested an access to the compiler farm.

François

diff --git a/libstdc++-v3/include/debug/forward_list 
b/libstdc++-v3/include/debug/forward_list
index 7d615978000..9a53de8afe2 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -1030,7 +1030,7 @@ namespace __gnu_debug
     {
       typedef typename std::__debug::forward_list<_Tp, _Alloc>::iterator _It;
 
-      static typename _Distance_traits<_It>::__type
+      static _GLIBCXX20_CONSTEXPR typename _Distance_traits<_It>::__type
       _S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq)
       {
        return __seq.empty()
diff --git a/libstdc++-v3/include/debug/functions.h 
b/libstdc++-v3/include/debug/functions.h
index 99a0c41758d..9626d344cbc 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -60,12 +60,8 @@ namespace __gnu_debug
                        unsigned int __line,
                        const char* __function)
     {
-      if (!std::__is_constant_evaluated())
-       {
-         __glibcxx_check_valid_range_at(__first, __last,
-                                        __file, __line, __function);
-       }
-
+      __glibcxx_check_valid_range_at(__first, __last,
+                                    __file, __line, __function);
       return __first;
     }
 
@@ -193,11 +189,14 @@ namespace __gnu_debug
 
   template<typename _Iterator, typename _Sequence, typename _Category,
           typename _InputIterator>
-    inline bool
+    inline _GLIBCXX20_CONSTEXPR bool
     __foreign_iterator(
        const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
        _InputIterator __other, _InputIterator __other_end)
     {
+      if (std::__is_constant_evaluated())
+       return true;
+
       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
       return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
     }
diff --git a/libstdc++-v3/include/debug/helper_functions.h 
b/libstdc++-v3/include/debug/helper_functions.h
index 8ef21684650..d693db16b95 100644
--- a/libstdc++-v3/include/debug/helper_functions.h
+++ b/libstdc++-v3/include/debug/helper_functions.h
@@ -116,11 +116,11 @@ namespace __gnu_debug
     }
 
   // An arbitrary iterator pointer is not singular.
-  inline bool
+  inline _GLIBCXX20_CONSTEXPR bool
   __check_singular_aux(const void*) { return false; }
 
   // Defined in <debug/safe_base.h>
-  bool
+  _GLIBCXX20_CONSTEXPR bool
   __check_singular_aux(const class _Safe_iterator_base*);
 
   // We may have an iterator that derives from _Safe_iterator_base but isn't
@@ -129,10 +129,7 @@ namespace __gnu_debug
     _GLIBCXX_CONSTEXPR
     inline bool
     __check_singular(_Iterator const& __x)
-    {
-      return ! std::__is_constant_evaluated()
-              && __gnu_debug::__check_singular_aux(std::__addressof(__x));
-    }
+    { return __gnu_debug::__check_singular_aux(std::__addressof(__x)); }
 
   /** Non-NULL pointers are nonsingular. */
   template<typename _Tp>
diff --git a/libstdc++-v3/include/debug/inplace_vector 
b/libstdc++-v3/include/debug/inplace_vector
index 750b0a7343c..1b01e0b0541 100644
--- a/libstdc++-v3/include/debug/inplace_vector
+++ b/libstdc++-v3/include/debug/inplace_vector
@@ -412,11 +412,6 @@ namespace __debug
        constexpr iterator
        emplace(const_iterator __position, _Args&&... __args)
        {
-         if (std::is_constant_evaluated())
-           return iterator(_Base::emplace(__position.base(),
-                                          std::forward<_Args>(__args)...),
-                           this);
-
          __glibcxx_check_insert(__position);
          const difference_type __offset = __position.base() - _Base::cbegin();
          _Base_iterator __res = _Base::emplace(__position.base(),
@@ -436,10 +431,7 @@ namespace __debug
       constexpr iterator
       insert(const_iterator __position, size_type __n, const _Tp& __x)
       {
-       if (std::is_constant_evaluated())
-         return iterator(_Base::insert(__position.base(), __n, __x), this);
-
-         __glibcxx_check_insert(__position);
+       __glibcxx_check_insert(__position);
        const difference_type __offset = __position.base() - _Base::cbegin();
        _Base_iterator __res = _Base::insert(__position.base(), __n, __x);
        _M_invalidate_after_nth(__offset);
@@ -451,11 +443,6 @@ namespace __debug
        insert(const_iterator __position, _InputIterator __first,
               _InputIterator __last)
        {
-         if (std::is_constant_evaluated())
-           return iterator(_Base::insert(__position.base(),
-                                         __gnu_debug::__unsafe(__first),
-                                         __gnu_debug::__unsafe(__last)), this);
-
          typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
          __glibcxx_check_insert_range(__position, __first, __last, __dist);
 
@@ -469,7 +456,7 @@ namespace __debug
            __res = _Base::insert(__position.base(), __first, __last);
 
          _M_invalidate_after_nth(__offset);
-         return { __res, this };
+         return iterator(__res, this);
        }
 
       template<__detail::__container_compatible_range<_Tp> _Rg>
@@ -488,9 +475,6 @@ namespace __debug
       constexpr iterator
       insert(const_iterator __position, initializer_list<_Tp> __il)
       {
-       if (std::is_constant_evaluated())
-         return iterator(_Base::insert(__position.base(), __il), this);
-
        __glibcxx_check_insert(__position);
        const auto __size = size();
        difference_type __offset = __position.base() - _Base::begin();
@@ -503,9 +487,6 @@ namespace __debug
       constexpr iterator
       erase(const_iterator __position)
       {
-       if (std::is_constant_evaluated())
-         return iterator(_Base::erase(__position.base()), this);
-
        __glibcxx_check_erase(__position);
        difference_type __offset = __position.base() - _Base::cbegin();
        _Base_iterator __res = _Base::erase(__position.base());
@@ -516,10 +497,6 @@ namespace __debug
       constexpr iterator
       erase(const_iterator __first, const_iterator __last)
       {
-       if (std::is_constant_evaluated())
-         return iterator(_Base::erase(__first.base(), __last.base()),
-                         this);
-
        __glibcxx_check_erase_range(__first, __last);
 
        if (__first.base() != __last.base())
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index d06e9e4c2f8..368128cc5a8 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -1063,7 +1063,7 @@ namespace __gnu_debug
     {
       typedef typename std::__debug::list<_Tp, _Alloc>::iterator _It;
 
-      static typename _Distance_traits<_It>::__type
+      static _GLIBCXX20_CONSTEXPR typename _Distance_traits<_It>::__type
       _S_size(const std::__debug::list<_Tp, _Alloc>& __seq)
       {
        return __seq.empty()
diff --git a/libstdc++-v3/include/debug/macros.h 
b/libstdc++-v3/include/debug/macros.h
index 84ad6d3fe9b..5d0961dfae4 100644
--- a/libstdc++-v3/include/debug/macros.h
+++ b/libstdc++-v3/include/debug/macros.h
@@ -38,10 +38,22 @@
  * the user error and where the error is reported.
  *
  */
+namespace __gnu_debug
+{
+  __attribute__((__always_inline__, __visibility__("default")))
+  inline void
+  __glibcxx_fail()
+  { }
+}
 
 #define _GLIBCXX_DEBUG_VERIFY_AT_F(_Cond,_ErrMsg,_File,_Line,_Func)    \
   do {                                                                 \
-    if (__builtin_expect(!bool(_Cond), false))                         \
+    if (std::__is_constant_evaluated())                                        
\
+      {                                                                        
\
+       if (!bool(_Cond))                                               \
+         __gnu_debug::__glibcxx_fail();                                \
+      }                                                                        
\
+    else if (__builtin_expect(!bool(_Cond), false))                    \
       __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func)                
\
        ._ErrMsg._M_error();                                            \
   } while (false)
diff --git a/libstdc++-v3/include/debug/safe_base.h 
b/libstdc++-v3/include/debug/safe_base.h
index 25ac7a4e836..e7fd41cbb0c 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_base.h
@@ -83,37 +83,27 @@ namespace __gnu_debug
     { }
 
     /** Initialize the iterator to reference the sequence pointed to
-     *  by @p __seq. @p __constant is true when we are initializing a
-     *  constant iterator, and false if it is a mutable iterator. Note
-     *  that @p __seq may be NULL, in which case the iterator will be
-     *  singular. Otherwise, the iterator will reference @p __seq and
-     *  be nonsingular.
-     */
+     * by @p __seq. @p __constant is true when we are initializing a
+     * constant iterator, and false if it is a mutable iterator. Note
+     * that @p __seq may be NULL, in which case the iterator will be
+     * singular. Otherwise, the iterator will reference @p __seq and
+     * be nonsingular. */
     _GLIBCXX20_CONSTEXPR
     _Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant)
     : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
-    {
-      if (!std::__is_constant_evaluated())
-       this->_M_attach(__seq, __constant);
-    }
+    { _M_attach_to(__seq, __constant); }
 
     /** Initializes the iterator to reference the same sequence that
-       @p __x does. @p __constant is true if this is a constant
-       iterator, and false if it is mutable. */
+     * @p __x does. @p __constant is true if this is a constant
+     * iterator, and false if it is mutable. */
     _GLIBCXX20_CONSTEXPR
     _Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant)
     : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
-    {
-      if (!std::__is_constant_evaluated())
-       this->_M_attach(__x._M_sequence, __constant);
-    }
+    { _M_attach_to(__x._M_sequence, __constant); }
 
     _GLIBCXX20_CONSTEXPR
     ~_Safe_iterator_base()
-    {
-      if (!std::__is_constant_evaluated())
-       this->_M_detach();
-    }
+    { _M_detach_sequence(); }
 
     /** For use in _Safe_iterator. */
     __gnu_cxx::__mutex&
@@ -122,10 +112,9 @@ namespace __gnu_debug
     /** Attaches this iterator to the given sequence, detaching it
      * from whatever sequence it was attached to originally. If the
      * new sequence is the NULL pointer, the iterator is left
-     * unattached.
-     */
-    void
-    _M_attach(const _Safe_sequence_base* __seq, bool __constant);
+     * unattached. */
+    _GLIBCXX20_CONSTEXPR void
+    _M_attach_to(const _Safe_sequence_base* __seq, bool __constant);
 
     /** Likewise, but not thread-safe. */
     void
@@ -133,22 +122,40 @@ namespace __gnu_debug
                     bool __constant) _GLIBCXX_USE_NOEXCEPT;
 
     /** Detach the iterator for whatever sequence it is attached to,
-     * if any.
-    */
+     * if any. */
+    _GLIBCXX20_CONSTEXPR void
+    _M_detach_sequence()
+    {
+      if (std::__is_constant_evaluated())
+       _M_sequence = 0;
+      else
+       _M_detach();
+    }
+
+  private:
+    void
+    _M_attach(const _Safe_sequence_base* __seq, bool __constant);
+
     void
     _M_detach();
 
 #if !_GLIBCXX_INLINE_VERSION
-  private:
-    /***************************************************************/
     /** Not-const method preserved for abi backward compatibility. */
     void
     _M_attach(_Safe_sequence_base* __seq, bool __constant);
 
+    /** Not-const method preserved for abi backward compatibility. */
     void
     _M_attach_single(_Safe_sequence_base* __seq,
                     bool __constant) _GLIBCXX_USE_NOEXCEPT;
-    /***************************************************************/
+
+    /* Not-constexpr method preserved for abi backward compatibility. */
+    _GLIBCXX_PURE bool
+    _M_singular() const _GLIBCXX_NOEXCEPT;
+
+    /* Not-constexpr method preserved for abi backward compatibility. */
+    _GLIBCXX_PURE bool
+    _M_can_compare(const _Safe_iterator_base& __x) const _GLIBCXX_USE_NOEXCEPT;
 #endif
 
   public:
@@ -157,22 +164,23 @@ namespace __gnu_debug
     _M_detach_single() _GLIBCXX_USE_NOEXCEPT;
 
     /** Determines if we are attached to the given sequence. */
-    bool
+    _GLIBCXX20_CONSTEXPR bool
     _M_attached_to(const _Safe_sequence_base* __seq) const
     { return _M_sequence == __seq; }
 
     /** Is this iterator singular? */
-    _GLIBCXX_PURE bool
-    _M_singular() const _GLIBCXX_USE_NOEXCEPT;
+    _GLIBCXX20_CONSTEXPR bool
+    _M_is_singular() const _GLIBCXX_USE_NOEXCEPT;
 
     /** Can we compare this iterator to the given iterator @p __x?
-       Returns true if both iterators are nonsingular and reference
-       the same sequence. */
-    _GLIBCXX_PURE bool
-    _M_can_compare(const _Safe_iterator_base& __x) const _GLIBCXX_USE_NOEXCEPT;
+     * Returns true if both iterators are nonsingular and reference
+     * the same sequence. */
+    _GLIBCXX20_CONSTEXPR bool
+    _M_is_comparable(const _Safe_iterator_base& __x) const 
_GLIBCXX_USE_NOEXCEPT
+    { return _M_sequence == __x._M_sequence; }
 
     /** Invalidate the iterator, making it singular. */
-    void
+    _GLIBCXX20_CONSTEXPR void
     _M_invalidate()
     { _M_version = 0; }
 
@@ -194,9 +202,9 @@ namespace __gnu_debug
   /** Iterators that derive from _Safe_iterator_base can be determined singular
    *  or non-singular.
    **/
-  inline bool
+  inline _GLIBCXX20_CONSTEXPR bool
   __check_singular_aux(const _Safe_iterator_base* __x)
-  { return __x->_M_singular(); }
+  { return __x->_M_is_singular(); }
 
   /**
    * @brief Base class that supports tracking of iterators that
@@ -352,6 +360,25 @@ namespace __gnu_debug
     void
     _M_detach_single(_Safe_iterator_base* __it) const _GLIBCXX_USE_NOEXCEPT;
   };
+
+  inline _GLIBCXX20_CONSTEXPR void
+  _Safe_iterator_base::_M_attach_to(const _Safe_sequence_base* __seq,
+                                   bool __constant)
+  {
+    if (std::__is_constant_evaluated())
+      {
+       _M_sequence = __seq;
+       _M_version = _M_sequence->_M_version;
+      }
+    else
+      _M_attach(__seq, __constant);
+  }
+
+  inline _GLIBCXX20_CONSTEXPR bool
+  _Safe_iterator_base::
+  _M_is_singular() const _GLIBCXX_USE_NOEXCEPT
+  { return !_M_sequence || _M_version != _M_sequence->_M_version; }
+
 } // namespace __gnu_debug
 
 #endif
diff --git a/libstdc++-v3/include/debug/safe_container.h 
b/libstdc++-v3/include/debug/safe_container.h
index 32159ba2176..4353f457691 100644
--- a/libstdc++-v3/include/debug/safe_container.h
+++ b/libstdc++-v3/include/debug/safe_container.h
@@ -58,7 +58,10 @@ namespace __gnu_debug
       _GLIBCXX20_CONSTEXPR
       void
       _M_swap_base(const _Safe_container& __x) const noexcept
-      { _Base::_M_swap(__x); }
+      {
+       if (!std::__is_constant_evaluated())
+         _Base::_M_swap(__x);
+      }
 
       _GLIBCXX20_CONSTEXPR
       _Safe_container(_Safe_container&& __x, const _Alloc&, std::true_type)
@@ -69,13 +72,10 @@ namespace __gnu_debug
       _Safe_container(_Safe_container&& __x, const _Alloc& __a, 
std::false_type)
       : _Safe_container()
       {
-       if (!std::__is_constant_evaluated())
-         {
-           if (__x._M_cont().get_allocator() == __a)
-             _M_swap_base(__x);
-           else
-             __x._M_invalidate_all();
-         }
+       if (__x._M_cont().get_allocator() == __a)
+         _M_swap_base(__x);
+       else
+         __x._M_invalidate_all();
       }
 
     protected:
@@ -106,9 +106,6 @@ namespace __gnu_debug
       _Safe_container&
       operator=(_Safe_container&& __x) noexcept
       {
-       if (std::__is_constant_evaluated())
-         return *this;
-
        if (std::__addressof(__x) == this)
          {
            // Standard containers have a valid but unspecified value after
diff --git a/libstdc++-v3/include/debug/safe_iterator.h 
b/libstdc++-v3/include/debug/safe_iterator.h
index 4da3d2bb3d4..56baf6103f2 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -40,7 +40,6 @@
 #endif
 
 #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \
-  if (!std::__is_constant_evaluated()) {                               \
   _GLIBCXX_DEBUG_VERIFY((!_Lhs._M_singular() && !_Rhs._M_singular())   \
                        || (_Lhs._M_value_initialized()                 \
                            && _Rhs._M_value_initialized()),            \
@@ -50,8 +49,7 @@
   _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs),                     \
                        _M_message(_DiffMsgId)                          \
                        ._M_iterator(_Lhs, #_Lhs)                       \
-                       ._M_iterator(_Rhs, #_Rhs));                     \
-  }
+                       ._M_iterator(_Rhs, #_Rhs));
 
 #define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs)                  \
   _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad,   \
@@ -88,12 +86,12 @@ namespace __gnu_debug
     struct _BeforeBeginHelper
     {
       template<typename _Iterator, typename _Category>
-       static bool
+       static _GLIBCXX20_CONSTEXPR bool
        _S_Is(const _Safe_iterator<_Iterator, _Sequence, _Category>&)
        { return false; }
 
       template<typename _Iterator, typename _Category>
-       static bool
+       static _GLIBCXX20_CONSTEXPR bool
        _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence, _Category>& 
__it)
        { return __it.base() == __it._M_get_sequence()->_M_base().begin(); }
     };
@@ -104,7 +102,7 @@ namespace __gnu_debug
     {
       typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
 
-      static typename _DistTraits::__type
+      static _GLIBCXX20_CONSTEXPR typename _DistTraits::__type
       _S_size(const _Sequence& __seq)
       { return std::make_pair(__seq.size(), __dp_exact); }
     };
@@ -131,9 +129,6 @@ namespace __gnu_debug
     : private _Iterator,
       public _Safe_iterator_base
     {
-      typedef _Iterator _Iter_base;
-      typedef _Safe_iterator_base _Safe_base;
-
       typedef std::iterator_traits<_Iterator> _Traits;
 
     protected:
@@ -149,11 +144,8 @@ namespace __gnu_debug
 
       _GLIBCXX20_CONSTEXPR
       _Safe_iterator(const _Safe_iterator& __x, _Unchecked) _GLIBCXX_NOEXCEPT
-      : _Iter_base(__x.base()), _Safe_base()
-      {
-       if (!std::__is_constant_evaluated())
-         _M_attach(__x._M_sequence);
-      }
+      : _Iterator(__x.base()), _Safe_iterator_base()
+      { _M_attach(__x._M_sequence); }
 
     public:
       typedef _Iterator                                        iterator_type;
@@ -169,7 +161,7 @@ namespace __gnu_debug
 
       /// @post the iterator is singular and unattached
       _GLIBCXX20_CONSTEXPR
-      _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { }
+      _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iterator() { }
 
       /**
        * @brief Safe iterator construction from an unsafe iterator and
@@ -181,7 +173,7 @@ namespace __gnu_debug
       _GLIBCXX20_CONSTEXPR
       _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
       _GLIBCXX_NOEXCEPT
-      : _Iter_base(__i), _Safe_base(__seq, _S_constant())
+      : _Iterator(__i), _Safe_iterator_base(__seq, _S_constant())
       { }
 
       /**
@@ -189,11 +181,8 @@ namespace __gnu_debug
        */
       _GLIBCXX20_CONSTEXPR
       _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
-      : _Iter_base(__x.base()), _Safe_base()
+      : _Iterator(__x.base()), _Safe_iterator_base()
       {
-       if (std::__is_constant_evaluated())
-         return;
-
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // DR 408. Is vector<reverse_iterator<char*> > forbidden?
        _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
@@ -211,14 +200,8 @@ namespace __gnu_debug
        */
       _GLIBCXX20_CONSTEXPR
       _Safe_iterator(_Safe_iterator&& __x) noexcept
-      : _Iter_base()
+      : _Iterator()
       {
-       if (std::__is_constant_evaluated())
-         {
-           base() = __x.base();
-           return;
-         }
-
        _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
                              || __x._M_value_initialized(),
                              _M_message(__msg_init_copy_singular)
@@ -243,11 +226,8 @@ namespace __gnu_debug
              std::__are_same<_MutableIterator, _OtherIterator>::__value,
                               _Category>::__type>& __x)
        _GLIBCXX_NOEXCEPT
-       : _Iter_base(__x.base())
+       : _Iterator(__x.base())
        {
-         if (std::__is_constant_evaluated())
-           return;
-
          // _GLIBCXX_RESOLVE_LIB_DEFECTS
          // DR 408. Is vector<reverse_iterator<char*> > forbidden?
          _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
@@ -265,12 +245,6 @@ namespace __gnu_debug
       _Safe_iterator&
       operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
       {
-       if (std::__is_constant_evaluated())
-         {
-           base() = __x.base();
-           return *this;
-         }
-
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // DR 408. Is vector<reverse_iterator<char*> > forbidden?
        _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
@@ -279,7 +253,8 @@ namespace __gnu_debug
                              ._M_iterator(*this, "this")
                              ._M_iterator(__x, "other"));
 
-       if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
+       if (!std::__is_constant_evaluated()
+           && this->_M_sequence && this->_M_sequence == __x._M_sequence)
          _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
            __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
            base() = __x.base();
@@ -304,12 +279,6 @@ namespace __gnu_debug
       _Safe_iterator&
       operator=(_Safe_iterator&& __x) noexcept
       {
-       if (std::__is_constant_evaluated())
-         {
-           base() = __x.base();
-           return *this;
-         }
-
        _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
                              || __x._M_value_initialized(),
                              _M_message(__msg_copy_singular)
@@ -319,7 +288,8 @@ namespace __gnu_debug
        if (std::__addressof(__x) == this)
          return *this;
 
-       if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
+       if (!std::__is_constant_evaluated()
+           && this->_M_sequence && this->_M_sequence == __x._M_sequence)
          _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
            __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
            base() = __x.base();
@@ -347,12 +317,9 @@ namespace __gnu_debug
       reference
       operator*() const _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
-                                 _M_message(__msg_bad_deref)
-                                 ._M_iterator(*this, "this"));
-         }
+       _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+                             _M_message(__msg_bad_deref)
+                             ._M_iterator(*this, "this"));
        return *base();
       }
 
@@ -365,12 +332,9 @@ namespace __gnu_debug
       pointer
       operator->() const _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
-                                 _M_message(__msg_bad_deref)
-                                 ._M_iterator(*this, "this"));
-         }
+       _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+                             _M_message(__msg_bad_deref)
+                             ._M_iterator(*this, "this"));
        return base().operator->();
       }
 
@@ -383,19 +347,18 @@ namespace __gnu_debug
       _Safe_iterator&
       operator++() _GLIBCXX_NOEXCEPT
       {
-       if (std::__is_constant_evaluated())
-         {
-           ++base();
-           return *this;
-         }
-
-       _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+       _GLIBCXX_DEBUG_VERIFY(_M_incrementable(),
                              _M_message(__msg_bad_inc)
                              ._M_iterator(*this, "this"));
-       _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
-         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+       if (std::__is_constant_evaluated())
          ++base();
-       } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+       else
+         {
+           _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
+             __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+             ++base();
+           } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+         }
        return *this;
       }
 
@@ -407,12 +370,9 @@ namespace __gnu_debug
       _Safe_iterator
       operator++(int) _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
-                                 _M_message(__msg_bad_inc)
-                                 ._M_iterator(*this, "this"));
-         }
+       _GLIBCXX_DEBUG_VERIFY(_M_incrementable(),
+                             _M_message(__msg_bad_inc)
+                             ._M_iterator(*this, "this"));
        _Safe_iterator __ret(*this, _Unchecked());
        ++*this;
        return __ret;
@@ -443,26 +403,40 @@ namespace __gnu_debug
       _GLIBCXX20_CONSTEXPR
       operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; }
 
+      /** Is this iterator singular? */
+      _GLIBCXX20_CONSTEXPR bool
+      _M_singular() const _GLIBCXX_USE_NOEXCEPT
+      { return this->_M_is_singular(); }
+
+      _GLIBCXX20_CONSTEXPR bool
+      _M_can_compare(const _Safe_iterator_base& __x) const 
_GLIBCXX_USE_NOEXCEPT
+      { return this->_M_is_comparable(__x); }
+
       /** Attach iterator to the given sequence. */
-      void
+      _GLIBCXX20_CONSTEXPR void
       _M_attach(const _Safe_sequence_base* __seq)
-      { _Safe_base::_M_attach(__seq, _S_constant()); }
+      { this->_M_attach_to(__seq, _S_constant()); }
 
       /** Likewise, but not thread-safe. */
       void
       _M_attach_single(const _Safe_sequence_base* __seq)
-      { _Safe_base::_M_attach_single(__seq, _S_constant()); }
+      { this->_M_attach_single(__seq, _S_constant()); }
+
+      /** Detach iterator from the sequence. */
+      _GLIBCXX20_CONSTEXPR void
+      _M_detach()
+      { this->_M_detach_sequence(); }
 
       /// Is the iterator dereferenceable?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_dereferenceable() const
-      { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
+      { return !_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
 
       /// Is the iterator before a dereferenceable one?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_before_dereferenceable() const
       {
-       if (this->_M_incrementable())
+       if (_M_incrementable())
        {
          _Iterator __base = base();
          return ++__base != _M_get_sequence()->_M_base().end();
@@ -471,17 +445,17 @@ namespace __gnu_debug
       }
 
       /// Is the iterator incrementable?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_incrementable() const
-      { return !this->_M_singular() && !_M_is_end(); }
+      { return !_M_singular() && !_M_is_end(); }
 
       /// Is the iterator value-initialized?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_value_initialized() const
-      { return _M_version == 0 && base() == _Iter_base(); }
+      { return _M_version == 0 && base() == _Iterator(); }
 
       // Can we advance the iterator @p __n steps (@p __n may be negative)
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_can_advance(difference_type __n, bool __strict = false) const;
 
       // Can we advance the iterator using @p __dist in @p __way direction.
@@ -491,13 +465,13 @@ namespace __gnu_debug
                       int __way) const;
 
       // Is the iterator range [*this, __rhs) valid?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_valid_range(const _Safe_iterator& __rhs,
                     std::pair<difference_type, _Distance_precision>& __dist,
                     bool __check_dereferenceable = true) const;
 
       // The sequence this iterator references.
-      typename __gnu_cxx::__conditional_type<
+      _GLIBCXX20_CONSTEXPR typename __gnu_cxx::__conditional_type<
        _IsConstant::__value, const _Sequence*, _Sequence*>::__type
       _M_get_sequence() const
       {
@@ -513,11 +487,11 @@ namespace __gnu_debug
       _M_get_distance_to(const _Safe_iterator& __rhs) const;
 
       // Get distance from sequence begin up to *this.
-      typename _Distance_traits<_Iterator>::__type
+      _GLIBCXX20_CONSTEXPR typename _Distance_traits<_Iterator>::__type
       _M_get_distance_from_begin() const;
 
       // Get distance from *this to sequence end.
-      typename _Distance_traits<_Iterator>::__type
+      _GLIBCXX20_CONSTEXPR typename _Distance_traits<_Iterator>::__type
       _M_get_distance_to_end() const;
 
       /// Is this iterator equal to the sequence's begin() iterator?
@@ -527,19 +501,19 @@ namespace __gnu_debug
       { return base() == _M_get_sequence()->_M_base().begin(); }
 
       /// Is this iterator equal to the sequence's end() iterator?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_is_end() const
       { return base() == _M_get_sequence()->_M_base().end(); }
 
       /// Is this iterator equal to the sequence's before_begin() iterator if
       /// any?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_is_before_begin() const
       { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); }
 
       /// Is this iterator equal to the sequence's before_begin() iterator if
       /// any or begin() otherwise?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_is_beginnest() const
       { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
 
@@ -690,6 +664,7 @@ namespace __gnu_debug
        *  @brief Iterator postincrement
        *  @pre iterator is incrementable
        */
+      _GLIBCXX20_CONSTEXPR
       _Safe_iterator
       operator++(int) _GLIBCXX_NOEXCEPT
       {
@@ -710,19 +685,20 @@ namespace __gnu_debug
       _Safe_iterator&
       operator--() _GLIBCXX_NOEXCEPT
       {
-       if (std::__is_constant_evaluated())
-         {
-           --this->base();
-           return *this;
-         }
-
        _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
                              _M_message(__msg_bad_dec)
                              ._M_iterator(*this, "this"));
-       _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
-         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+
+       if (std::__is_constant_evaluated())
          --this->base();
-       } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+       else
+         {
+           _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
+             __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+             --this->base();
+           } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+         }
+
        return *this;
       }
 
@@ -730,6 +706,7 @@ namespace __gnu_debug
        *  @brief Iterator postdecrement
        *  @pre iterator is decrementable
        */
+      _GLIBCXX20_CONSTEXPR
       _Safe_iterator
       operator--(int) _GLIBCXX_NOEXCEPT
       {
@@ -744,7 +721,7 @@ namespace __gnu_debug
       // ------ Utilities ------
 
       // Is the iterator decrementable?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_decrementable() const
       { return !this->_M_singular() && !this->_M_is_begin(); }
     };
@@ -838,7 +815,7 @@ namespace __gnu_debug
 #endif
 
       // Is the iterator range [*this, __rhs) valid?
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_valid_range(const _Safe_iterator& __rhs,
                     std::pair<difference_type,
                               _Distance_precision>& __dist) const;
@@ -864,12 +841,9 @@ namespace __gnu_debug
       _Safe_iterator
       operator++(int) _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
-                                 _M_message(__msg_bad_inc)
-                                 ._M_iterator(*this, "this"));
-         }
+       _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+                             _M_message(__msg_bad_inc)
+                             ._M_iterator(*this, "this"));
        _Safe_iterator __ret(*this, _Unchecked());
        ++*this;
        return __ret;
@@ -896,12 +870,9 @@ namespace __gnu_debug
       _Safe_iterator
       operator--(int) _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
-                                 _M_message(__msg_bad_dec)
-                                 ._M_iterator(*this, "this"));
-         }
+       _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
+                             _M_message(__msg_bad_dec)
+                             ._M_iterator(*this, "this"));
        _Safe_iterator __ret(*this, _Unchecked());
        --*this;
        return __ret;
@@ -913,13 +884,10 @@ namespace __gnu_debug
       reference
       operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
-                                 && this->_M_can_advance(__n + 1),
-                                 _M_message(__msg_iter_subscript_oob)
-                                 ._M_iterator(*this)._M_integer(__n));
-         }
+       _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
+                             && this->_M_can_advance(__n + 1),
+                             _M_message(__msg_iter_subscript_oob)
+                             ._M_iterator(*this)._M_integer(__n));
        return this->base()[__n];
       }
 
@@ -927,19 +895,18 @@ namespace __gnu_debug
       _Safe_iterator&
       operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
       {
-       if (std::__is_constant_evaluated())
-         {
-           this->base() += __n;
-           return *this;
-         }
-
        _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
                              _M_message(__msg_advance_oob)
                              ._M_iterator(*this)._M_integer(__n));
-       _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
-         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+       if (std::__is_constant_evaluated())
          this->base() += __n;
-       } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+       else
+         {
+           _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
+             __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+             this->base() += __n;
+           } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+         }
        return *this;
       }
 
@@ -947,19 +914,18 @@ namespace __gnu_debug
       _Safe_iterator&
       operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
       {
-       if (std::__is_constant_evaluated())
-         {
-           this->base() -= __n;
-           return *this;
-         }
-
        _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
                              _M_message(__msg_retreat_oob)
                              ._M_iterator(*this)._M_integer(__n));
-       _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
-         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+       if (std::__is_constant_evaluated())
          this->base() -= __n;
-       } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+       else
+         {
+           _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN {
+             __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+             this->base() -= __n;
+           } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END
+         }
        return *this;
       }
 
@@ -983,6 +949,7 @@ namespace __gnu_debug
       }
 #else
       _GLIBCXX_NODISCARD
+      _GLIBCXX20_CONSTEXPR
       friend bool
       operator<(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
       {
@@ -991,6 +958,7 @@ namespace __gnu_debug
       }
 
       _GLIBCXX_NODISCARD
+      _GLIBCXX20_CONSTEXPR
       friend bool
       operator<(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
       {
@@ -999,6 +967,7 @@ namespace __gnu_debug
       }
 
       _GLIBCXX_NODISCARD
+      _GLIBCXX20_CONSTEXPR
       friend bool
       operator<=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
       {
@@ -1007,6 +976,7 @@ namespace __gnu_debug
       }
 
       _GLIBCXX_NODISCARD
+      _GLIBCXX20_CONSTEXPR
       friend bool
       operator<=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
       {
@@ -1015,6 +985,7 @@ namespace __gnu_debug
       }
 
       _GLIBCXX_NODISCARD
+      _GLIBCXX20_CONSTEXPR
       friend bool
       operator>(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
       {
@@ -1023,6 +994,7 @@ namespace __gnu_debug
       }
 
       _GLIBCXX_NODISCARD
+      _GLIBCXX20_CONSTEXPR
       friend bool
       operator>(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
       {
@@ -1031,6 +1003,7 @@ namespace __gnu_debug
       }
 
       _GLIBCXX_NODISCARD
+      _GLIBCXX20_CONSTEXPR
       friend bool
       operator>=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
       {
@@ -1039,6 +1012,7 @@ namespace __gnu_debug
       }
 
       _GLIBCXX_NODISCARD
+      _GLIBCXX20_CONSTEXPR
       friend bool
       operator>=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
       {
@@ -1074,12 +1048,9 @@ namespace __gnu_debug
       friend _Self
       operator+(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
-                                 _M_message(__msg_advance_oob)
-                                 ._M_iterator(__x)._M_integer(__n));
-         }
+       _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
+                             _M_message(__msg_advance_oob)
+                             ._M_iterator(__x)._M_integer(__n));
        return _Safe_iterator(__x.base() + __n, __x._M_sequence);
       }
 
@@ -1088,12 +1059,9 @@ namespace __gnu_debug
       friend _Self
       operator+(difference_type __n, const _Self& __x) _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
-                                 _M_message(__msg_advance_oob)
-                                 ._M_iterator(__x)._M_integer(__n));
-         }
+       _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
+                             _M_message(__msg_advance_oob)
+                             ._M_iterator(__x)._M_integer(__n));
        return _Safe_iterator(__n + __x.base(), __x._M_sequence);
       }
 
@@ -1102,12 +1070,9 @@ namespace __gnu_debug
       friend _Self
       operator-(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
-                                 _M_message(__msg_retreat_oob)
-                                 ._M_iterator(__x)._M_integer(__n));
-         }
+       _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
+                             _M_message(__msg_retreat_oob)
+                             ._M_iterator(__x)._M_integer(__n));
        return _Safe_iterator(__x.base() - __n, __x._M_sequence);
       }
     };
@@ -1121,12 +1086,7 @@ namespace __gnu_debug
                  const _Safe_iterator<_Iterator, _Sequence,
                                       _Category>& __last,
                  typename _Distance_traits<_Iterator>::__type& __dist)
-    {
-      if (std::__is_constant_evaluated())
-       return true;
-
-      return __first._M_valid_range(__last, __dist);
-    }
+    { return __first._M_valid_range(__last, __dist); }
 
   template<typename _Iterator, typename _Sequence, typename _Category>
     _GLIBCXX20_CONSTEXPR
@@ -1136,9 +1096,6 @@ namespace __gnu_debug
                  const _Safe_iterator<_Iterator, _Sequence,
                                       _Category>& __last)
     {
-      if (std::__is_constant_evaluated())
-       return true;
-
       typename _Distance_traits<_Iterator>::__type __dist;
       return __first._M_valid_range(__last, __dist);
     }
@@ -1149,12 +1106,7 @@ namespace __gnu_debug
     inline bool
     __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
                  _Size __n)
-    { 
-      if (std::__is_constant_evaluated())
-       return true;
-
-      return __it._M_can_advance(__n);
-    }
+    { return __it._M_can_advance(__n); }
 
   template<typename _Iterator, typename _Sequence, typename _Category,
           typename _Diff>
@@ -1163,12 +1115,7 @@ namespace __gnu_debug
     __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
                  const std::pair<_Diff, _Distance_precision>& __dist,
                  int __way)
-    {
-      if (std::__is_constant_evaluated())
-       return true;
-    
-      return __it._M_can_advance(__dist, __way);
-    }
+    { return __it._M_can_advance(__dist, __way); }
 
   template<typename _Iterator, typename _Sequence>
     _GLIBCXX20_CONSTEXPR _Iterator
diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc 
b/libstdc++-v3/include/debug/safe_iterator.tcc
index 715eceb92f3..11cde2a2a5e 100644
--- a/libstdc++-v3/include/debug/safe_iterator.tcc
+++ b/libstdc++-v3/include/debug/safe_iterator.tcc
@@ -34,7 +34,7 @@
 namespace __gnu_debug
 {
   template<typename _Iterator, typename _Sequence, typename _Category>
-    typename _Distance_traits<_Iterator>::__type
+    _GLIBCXX20_CONSTEXPR typename _Distance_traits<_Iterator>::__type
     _Safe_iterator<_Iterator, _Sequence, _Category>::
     _M_get_distance_from_begin() const
     {
@@ -58,7 +58,7 @@ namespace __gnu_debug
     }
 
   template<typename _Iterator, typename _Sequence, typename _Category>
-    typename _Distance_traits<_Iterator>::__type
+    _GLIBCXX20_CONSTEXPR typename _Distance_traits<_Iterator>::__type
     _Safe_iterator<_Iterator, _Sequence, _Category>::
     _M_get_distance_to_end() const
     {
@@ -82,7 +82,7 @@ namespace __gnu_debug
     }
 
   template<typename _Iterator, typename _Sequence, typename _Category>
-    bool
+    _GLIBCXX20_CONSTEXPR bool
     _Safe_iterator<_Iterator, _Sequence, _Category>::
     _M_can_advance(difference_type __n, bool __strict) const
     {
@@ -191,7 +191,7 @@ namespace __gnu_debug
     }
 
   template<typename _Iterator, typename _Sequence, typename _Category>
-    bool
+    _GLIBCXX20_CONSTEXPR bool
     _Safe_iterator<_Iterator, _Sequence, _Category>::
     _M_valid_range(const _Safe_iterator& __rhs,
                   std::pair<difference_type, _Distance_precision>& __dist,
@@ -221,7 +221,7 @@ namespace __gnu_debug
     }
 
   template<typename _Iterator, typename _Sequence>
-    bool
+    _GLIBCXX20_CONSTEXPR bool
     _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>::
     _M_valid_range(const _Safe_iterator& __rhs,
                   std::pair<difference_type,
diff --git a/libstdc++-v3/include/debug/safe_local_iterator.h 
b/libstdc++-v3/include/debug/safe_local_iterator.h
index d37168a040b..391ddb5cde1 100644
--- a/libstdc++-v3/include/debug/safe_local_iterator.h
+++ b/libstdc++-v3/include/debug/safe_local_iterator.h
@@ -65,9 +65,6 @@ namespace __gnu_debug
     : private _Iterator
     , public _Safe_local_iterator_base
     {
-      typedef _Iterator _Iter_base;
-      typedef _Safe_local_iterator_base _Safe_base;
-
       typedef typename _UContainer::size_type size_type;
 
       typedef std::iterator_traits<_Iterator> _Traits;
@@ -87,7 +84,7 @@ namespace __gnu_debug
 
       _Safe_local_iterator(const _Safe_local_iterator& __x,
                           _Unchecked) noexcept
-      : _Iter_base(__x.base())
+      : _Iterator(__x.base())
       { _M_attach(__x._M_safe_container()); }
 
     public:
@@ -99,7 +96,7 @@ namespace __gnu_debug
       typedef typename _Traits::pointer                        pointer;
 
       /// @post the iterator is singular and unattached
-      _Safe_local_iterator() noexcept : _Iter_base() { }
+      _Safe_local_iterator() noexcept : _Iterator() { }
 
       /**
        * @brief Safe iterator construction from an unsafe iterator and
@@ -110,14 +107,14 @@ namespace __gnu_debug
        */
       _Safe_local_iterator(_Iterator __i,
                           const _Safe_unordered_container_base* __cont)
-      : _Iter_base(__i), _Safe_base(__cont, _S_constant())
+      : _Iterator(__i), _Safe_local_iterator_base(__cont, _S_constant())
       { }
 
       /**
        * @brief Copy construction.
        */
       _Safe_local_iterator(const _Safe_local_iterator& __x) noexcept
-      : _Iter_base(__x.base())
+      : _Iterator(__x.base())
       {
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // DR 408. Is vector<reverse_iterator<char*> > forbidden?
@@ -134,7 +131,7 @@ namespace __gnu_debug
        * @post __x is singular and unattached
        */
       _Safe_local_iterator(_Safe_local_iterator&& __x) noexcept
-      : _Iter_base()
+      : _Iterator()
       {
        _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
                              || __x._M_value_initialized(),
@@ -157,7 +154,7 @@ namespace __gnu_debug
          typename __gnu_cxx::__enable_if<_IsConstant::__value &&
            std::__are_same<_MutableIterator, _OtherIterator>::__value,
                                          _UContainer>::__type>& __x) noexcept
-       : _Iter_base(__x.base())
+       : _Iterator(__x.base())
        {
          // _GLIBCXX_RESOLVE_LIB_DEFECTS
          // DR 408. Is vector<reverse_iterator<char*> > forbidden?
@@ -240,7 +237,7 @@ namespace __gnu_debug
       reference
       operator*() const
       {
-       _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+       _GLIBCXX_DEBUG_VERIFY(_M_dereferenceable(),
                              _M_message(__msg_bad_deref)
                              ._M_iterator(*this, "this"));
        return *base();
@@ -253,7 +250,7 @@ namespace __gnu_debug
       pointer
       operator->() const
       {
-       _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+       _GLIBCXX_DEBUG_VERIFY(_M_dereferenceable(),
                              _M_message(__msg_bad_deref)
                              ._M_iterator(*this, "this"));
        return base().operator->();
@@ -267,7 +264,7 @@ namespace __gnu_debug
       _Safe_local_iterator&
       operator++()
       {
-       _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+       _GLIBCXX_DEBUG_VERIFY(_M_incrementable(),
                              _M_message(__msg_bad_inc)
                              ._M_iterator(*this, "this"));
        __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
@@ -282,7 +279,7 @@ namespace __gnu_debug
       _Safe_local_iterator
       operator++(int)
       {
-       _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+       _GLIBCXX_DEBUG_VERIFY(_M_incrementable(),
                              _M_message(__msg_bad_inc)
                              ._M_iterator(*this, "this"));
        _Safe_local_iterator __ret(*this, _Unchecked{});
@@ -318,30 +315,39 @@ namespace __gnu_debug
        */
       operator _Iterator() const { return *this; }
 
+      /** Is this iterator singular? */
+      _GLIBCXX20_CONSTEXPR bool
+      _M_singular() const noexcept
+      { return this->_M_is_singular(); }
+
+      _GLIBCXX20_CONSTEXPR bool
+      _M_can_compare(const _Safe_iterator_base& __x) const noexcept
+      { return this->_M_is_comparable(__x); }
+
       /** Attach iterator to the given unordered container. */
-      void
+      _GLIBCXX20_CONSTEXPR void
       _M_attach(const _Safe_unordered_container_base* __cont)
-      { _Safe_base::_M_attach(__cont, _S_constant()); }
+      { _Safe_local_iterator_base::_M_attach(__cont, _S_constant()); }
 
       /** Likewise, but not thread-safe. */
       void
       _M_attach_single(const _Safe_unordered_container_base* __cont)
-      { _Safe_base::_M_attach_single(__cont, _S_constant()); }
+      { _Safe_local_iterator_base::_M_attach_single(__cont, _S_constant()); }
 
       /// Is the iterator dereferenceable?
       bool
       _M_dereferenceable() const
-      { return !this->_M_singular() && !_M_is_end(); }
+      { return !_M_singular() && !_M_is_end(); }
 
       /// Is the iterator incrementable?
       bool
       _M_incrementable() const
-      { return !this->_M_singular() && !_M_is_end(); }
+      { return !_M_singular() && !_M_is_end(); }
 
       /// Is the iterator value-initialized?
       bool
       _M_value_initialized() const
-      { return _M_version == 0 && base() == _Iter_base{}; }
+      { return _M_version == 0 && base() == _Iterator{}; }
 
       // Is the iterator range [*this, __rhs) valid?
       bool
diff --git a/libstdc++-v3/include/debug/safe_sequence.h 
b/libstdc++-v3/include/debug/safe_sequence.h
index e7658bb26a7..4415f689c9f 100644
--- a/libstdc++-v3/include/debug/safe_sequence.h
+++ b/libstdc++-v3/include/debug/safe_sequence.h
@@ -110,6 +110,10 @@ namespace __gnu_debug
   template<typename _Sequence>
     class _Safe_sequence : public _Safe_sequence_base
     {
+      template<typename _Predicate>
+       void
+       _M_invalidate_if_impl(_Predicate __pred) const;
+
     public:
       /** Invalidates all iterators @c x that reference this sequence,
          are not singular, and for which @c __pred(x) returns @c
@@ -117,7 +121,13 @@ namespace __gnu_debug
          in the safe ones. */
       template<typename _Predicate>
        _GLIBCXX20_CONSTEXPR void
-       _M_invalidate_if(_Predicate __pred) const;
+       _M_invalidate_if(_Predicate __pred) const
+       {
+         if (std::__is_constant_evaluated())
+           return;
+
+         _M_invalidate_if_impl(__pred);
+       }
 
       /** Transfers all iterators @c x that reference @c from sequence,
          are not singular, and for which @c __pred(x) returns @c
diff --git a/libstdc++-v3/include/debug/safe_sequence.tcc 
b/libstdc++-v3/include/debug/safe_sequence.tcc
index 884478fad9d..f55767258be 100644
--- a/libstdc++-v3/include/debug/safe_sequence.tcc
+++ b/libstdc++-v3/include/debug/safe_sequence.tcc
@@ -33,13 +33,10 @@ namespace __gnu_debug
 {
   template<typename _Sequence>
     template<typename _Predicate>
-      _GLIBCXX20_CONSTEXPR void
+      void
       _Safe_sequence<_Sequence>::
-      _M_invalidate_if(_Predicate __pred) const
+      _M_invalidate_if_impl(_Predicate __pred) const
       {
-       if (std::__is_constant_evaluated())
-         return;
-
        typedef typename _Sequence::iterator iterator;
        typedef typename _Sequence::const_iterator const_iterator;
 
diff --git a/libstdc++-v3/include/debug/safe_unordered_base.h 
b/libstdc++-v3/include/debug/safe_unordered_base.h
index 603ceff9a86..427067aaf4e 100644
--- a/libstdc++-v3/include/debug/safe_unordered_base.h
+++ b/libstdc++-v3/include/debug/safe_unordered_base.h
@@ -74,9 +74,9 @@ namespace __gnu_debug
        iterator, and false if it is mutable. */
     _Safe_local_iterator_base(const _Safe_local_iterator_base& __x,
                              bool __constant)
-    { this->_M_attach(__x._M_safe_container(), __constant); }
+    { _M_attach(__x._M_safe_container(), __constant); }
 
-    ~_Safe_local_iterator_base() { this->_M_detach(); }
+    ~_Safe_local_iterator_base() { _M_detach(); }
 
     /** Attaches this iterator to the given container, detaching it
      * from whatever container it was attached to originally. If the
diff --git a/libstdc++-v3/include/debug/vector 
b/libstdc++-v3/include/debug/vector
index 61e5ff78a7a..ca9c9169226 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -103,7 +103,7 @@ namespace __gnu_debug
 
       size_type _M_guaranteed_capacity;
 
-      bool
+      _GLIBCXX20_CONSTEXPR bool
       _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
       { return __elements > _M_seq().capacity(); }
 
@@ -213,8 +213,8 @@ namespace __debug
        _GLIBCXX20_CONSTEXPR
        vector(_InputIterator __first, _InputIterator __last,
               const _Allocator& __a = _Allocator())
-       : _Base(__gnu_debug::__base(std::__is_constant_evaluated() ? __first
-                 : __glibcxx_check_valid_constructor_range(__first, __last)),
+       : _Base(__gnu_debug::__base(
+                 __glibcxx_check_valid_constructor_range(__first, __last)),
                __gnu_debug::__base(__last), __a) { }
 
 #if __cplusplus < 201103L
@@ -277,11 +277,8 @@ namespace __debug
       operator=(initializer_list<value_type> __l)
       {
        _Base::operator=(__l);
-       if (!std::__is_constant_evaluated())
-         {
-           this->_M_invalidate_all();
-           this->_M_update_guaranteed_capacity();
-         }
+       this->_M_invalidate_all();
+       this->_M_update_guaranteed_capacity();
        return *this;
       }
 #endif
@@ -296,10 +293,6 @@ namespace __debug
        void
        assign(_InputIterator __first, _InputIterator __last)
        {
-         if (std::__is_constant_evaluated())
-           return _Base::assign(__gnu_debug::__unsafe(__first),
-                                __gnu_debug::__unsafe(__last));
-
          typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
          __glibcxx_check_valid_range2(__first, __last, __dist);
 
@@ -318,11 +311,8 @@ namespace __debug
       assign(size_type __n, const _Tp& __u)
       {
        _Base::assign(__n, __u);
-       if (!std::__is_constant_evaluated())
-         {
-           this->_M_invalidate_all();
-           this->_M_update_guaranteed_capacity();
-         }
+       this->_M_invalidate_all();
+       this->_M_update_guaranteed_capacity();
       }
 
 #if __cplusplus >= 201103L
@@ -331,11 +321,8 @@ namespace __debug
       assign(initializer_list<value_type> __l)
       {
        _Base::assign(__l);
-       if (!std::__is_constant_evaluated())
-         {
-           this->_M_invalidate_all();
-           this->_M_update_guaranteed_capacity();
-         }
+       this->_M_invalidate_all();
+       this->_M_update_guaranteed_capacity();
       }
 #endif
 
@@ -425,9 +412,6 @@ namespace __debug
       void
       resize(size_type __sz)
       {
-       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);
@@ -441,9 +425,6 @@ namespace __debug
       void
       resize(size_type __sz, const _Tp& __c)
       {
-       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);
@@ -471,9 +452,6 @@ namespace __debug
       void
       shrink_to_fit()
       {
-       if (std::__is_constant_evaluated())
-         return _Base::shrink_to_fit();
-
        if (_Base::_M_shrink_to_fit())
          {
            this->_M_guaranteed_capacity = _Base::capacity();
@@ -487,9 +465,6 @@ namespace __debug
       size_type
       capacity() const _GLIBCXX_NOEXCEPT
       {
-       if (std::__is_constant_evaluated())
-         return _Base::capacity();
-
 #ifdef _GLIBCXX_DEBUG_PEDANTIC
        return this->_M_guaranteed_capacity;
 #else
@@ -503,9 +478,6 @@ namespace __debug
       void
       reserve(size_type __n)
       {
-       if (std::__is_constant_evaluated())
-         return _Base::reserve(__n);
-
        bool __realloc = this->_M_requires_reallocation(__n);
        _Base::reserve(__n);
        if (__n > this->_M_guaranteed_capacity)
@@ -580,9 +552,6 @@ namespace __debug
       void
       push_back(const _Tp& __x)
       {
-       if (std::__is_constant_evaluated())
-         return _Base::push_back(__x);
-
        bool __realloc = this->_M_requires_reallocation(this->size() + 1);
        _Base::push_back(__x);
        if (__realloc)
@@ -607,9 +576,6 @@ namespace __debug
 #endif
        emplace_back(_Args&&... __args)
        {
-         if (std::__is_constant_evaluated())
-           return _Base::emplace_back(std::forward<_Args>(__args)...);
-
          bool __realloc = this->_M_requires_reallocation(this->size() + 1);
          _Base::emplace_back(std::forward<_Args>(__args)...);
          if (__realloc)
@@ -625,11 +591,8 @@ namespace __debug
       void
       pop_back() _GLIBCXX_NOEXCEPT
       {
-       if (!std::__is_constant_evaluated())
-         {
-           __glibcxx_check_nonempty();
-           this->_M_invalidate_if(_Equal(--_Base::end()));
-         }
+       __glibcxx_check_nonempty();
+       this->_M_invalidate_if(_Equal(--_Base::end()));
        _Base::pop_back();
       }
 
@@ -639,11 +602,6 @@ namespace __debug
        iterator
        emplace(const_iterator __position, _Args&&... __args)
        {
-         if (std::__is_constant_evaluated())
-           return iterator(_Base::emplace(__position.base(),
-                                          std::forward<_Args>(__args)...),
-                           this);
-
          __glibcxx_check_insert(__position);
          bool __realloc = this->_M_requires_reallocation(this->size() + 1);
          difference_type __offset = __position.base() - _Base::cbegin();
@@ -666,9 +624,6 @@ namespace __debug
       insert(iterator __position, const _Tp& __x)
 #endif
       {
-       if (std::__is_constant_evaluated())
-         return iterator(_Base::insert(__position.base(), __x), this);
-
        __glibcxx_check_insert(__position);
        bool __realloc = this->_M_requires_reallocation(this->size() + 1);
        difference_type __offset = __position.base() - _Base::begin();
@@ -700,9 +655,6 @@ namespace __debug
       iterator
       insert(const_iterator __position, size_type __n, const _Tp& __x)
       {
-       if (std::__is_constant_evaluated())
-         return iterator(_Base::insert(__position.base(), __n, __x), this);
-
        __glibcxx_check_insert(__position);
        bool __realloc = this->_M_requires_reallocation(this->size() + __n);
        difference_type __offset = __position.base() - _Base::cbegin();
@@ -738,11 +690,6 @@ namespace __debug
        insert(const_iterator __position,
               _InputIterator __first, _InputIterator __last)
        {
-         if (std::__is_constant_evaluated())
-           return iterator(_Base::insert(__position.base(),
-                                         __gnu_debug::__unsafe(__first),
-                                         __gnu_debug::__unsafe(__last)), this);
-
          typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
          __glibcxx_check_insert_range(__position, __first, __last, __dist);
 
@@ -802,9 +749,6 @@ namespace __debug
       erase(iterator __position)
 #endif
       {
-       if (std::__is_constant_evaluated())
-         return iterator(_Base::erase(__position.base()), this);
-
        __glibcxx_check_erase(__position);
        difference_type __offset = __position.base() - _Base::begin();
        _Base_iterator __res = _Base::erase(__position.base());
@@ -820,9 +764,6 @@ namespace __debug
       erase(iterator __first, iterator __last)
 #endif
       {
-       if (std::__is_constant_evaluated())
-         return iterator(_Base::erase(__first.base(), __last.base()), this);
-
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 151. can't currently clear() empty container
        __glibcxx_check_erase_range(__first, __last);
@@ -848,8 +789,7 @@ namespace __debug
       swap(vector& __x)
       _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
       {
-       if (!std::__is_constant_evaluated())
-         _Safe::_M_swap(__x);
+       _Safe::_M_swap(__x);
        _Base::swap(__x);
        std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
       }
@@ -859,8 +799,7 @@ namespace __debug
       clear() _GLIBCXX_NOEXCEPT
       {
        _Base::clear();
-       if (!std::__is_constant_evaluated())
-         this->_M_invalidate_all();
+       this->_M_invalidate_all();
       }
 
       _GLIBCXX20_CONSTEXPR
@@ -879,14 +818,11 @@ namespace __debug
          auto __old_capacity = _Base::capacity();
          auto __old_size = _Base::size();
          _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();
-           }
+         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();
        }
 
       template<__detail::__container_compatible_range<_Tp> _Rg>
@@ -895,12 +831,9 @@ namespace __debug
        {
          auto __old_capacity = _Base::capacity();
          auto __res = _Base::insert_range(__pos.base(), __rg);
-         if (!std::__is_constant_evaluated())
-           {
-             if (_Base::capacity() != __old_capacity)
-               this->_M_invalidate_all();
-             this->_M_update_guaranteed_capacity();
-           }
+         if (_Base::capacity() != __old_capacity)
+           this->_M_invalidate_all();
+         this->_M_update_guaranteed_capacity();
          return iterator(__res, this);
        }
 
@@ -910,17 +843,14 @@ namespace __debug
        {
          auto __old_capacity = _Base::capacity();
          _Base::append_range(__rg);
-         if (!std::__is_constant_evaluated())
-           {
-             if (_Base::capacity() != __old_capacity)
-               this->_M_invalidate_all();
-             this->_M_update_guaranteed_capacity();
-           }
+         if (_Base::capacity() != __old_capacity)
+           this->_M_invalidate_all();
+         this->_M_update_guaranteed_capacity();
        }
 #endif
 
     private:
-      void
+      _GLIBCXX20_CONSTEXPR void
       _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
       {
        typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index 3e6f286bc0a..a79dab9497d 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -346,7 +346,7 @@ namespace __gnu_debug
       {
        _Safe_iterator_base* __old = __iter;
        __iter = __iter->_M_next;
-       if (__old->_M_singular())
+       if (__old->_M_is_singular())
          __old->_M_detach_single();
       }
 
@@ -354,7 +354,7 @@ namespace __gnu_debug
       {
        _Safe_iterator_base* __old = __iter2;
        __iter2 = __iter2->_M_next;
-       if (__old->_M_singular())
+       if (__old->_M_is_singular())
          __old->_M_detach_single();
       }
   }
@@ -462,7 +462,7 @@ namespace __gnu_debug
     __it->_M_unlink();
     if (_M_const_iterators == __it)
       _M_const_iterators = __it->_M_next;
-    if (_M_iterators == __it)
+    else if (_M_iterators == __it)
       _M_iterators = __it->_M_next;
   }
 
@@ -541,15 +541,17 @@ namespace __gnu_debug
     _M_next = 0;
   }
 
+#if !_GLIBCXX_INLINE_VERSION
   bool
   _Safe_iterator_base::
   _M_singular() const noexcept
-  { return !_M_sequence || _M_version != _M_sequence->_M_version; }
+  { return _M_is_singular(); }
 
   bool
   _Safe_iterator_base::
   _M_can_compare(const _Safe_iterator_base& __x) const noexcept
-  { return _M_sequence == __x._M_sequence; }
+  { return _M_is_comparable(__x); }
+#endif
 
   __gnu_cxx::__mutex&
   _Safe_iterator_base::
@@ -711,7 +713,7 @@ namespace __gnu_debug
     __it->_M_unlink();
     if (_M_const_local_iterators == __it)
       _M_const_local_iterators = __it->_M_next;
-    if (_M_local_iterators == __it)
+    else if (_M_local_iterators == __it)
       _M_local_iterators = __it->_M_next;
   }
 

Reply via email to