On Wed, 6 Dec 2023 at 14:30, Jonathan Wakely wrote:
>
> Any comments on this approach?
Pushed to trunk now.
>
> -- >8 --
>
> This makes constexpr std::vector (mostly) work in Debug Mode. All safe
> iterator instrumentation and checking is disabled during constant
> evaluation, because it requires mutex locks and calls to non-inline
> functions defined in libstdc++.so. It should be OK to disable the safety
> checks, because most UB should be detected during constant evaluation
> anyway.
>
> We could try to enable the full checking in constexpr, but it would mean
> wrapping all the non-inline functions like _M_attach with an inline
> _M_constexpr_attach that does the iterator housekeeping inline without
> mutex locks when calling for constant evaluation, and calls the
> non-inline function at runtime. That could be done in future if we find
> that we've lost safety or useful checking by disabling the safe
> iterators.
>
> There are a few test failures in C++20 mode, which I'm unable to
> explain. The _Safe_iterator::operator++() member gives errors for using
> non-constexpr functions during constant evaluation, even though those
> functions are guarded by std::is_constant_evaluated() checks. The same
> code works fine for C++23 and up.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/109536
> * include/bits/c++config (__glibcxx_constexpr_assert): Remove
> macro.
> * include/bits/stl_algobase.h (__niter_base, __copy_move_a)
> (__copy_move_backward_a, __fill_a, __fill_n_a, __equal_aux)
> (__lexicographical_compare_aux): Add constexpr to overloads for
> debug mode iterators.
> * include/debug/helper_functions.h (__unsafe): Add constexpr.
> * include/debug/macros.h (_GLIBCXX_DEBUG_VERIFY_COND_AT): Remove
> macro, folding it into ...
> (_GLIBCXX_DEBUG_VERIFY_AT_F): ... here. Do not use
> __glibcxx_constexpr_assert.
> * include/debug/safe_base.h (_Safe_iterator_base): Add constexpr
> to some member functions. Omit attaching, detaching and checking
> operations during constant evaluation.
> * include/debug/safe_container.h (_Safe_container): Likewise.
> * include/debug/safe_iterator.h (_Safe_iterator): Likewise.
> * include/debug/safe_iterator.tcc (__niter_base, __copy_move_a)
> (__copy_move_backward_a, __fill_a, __fill_n_a, __equal_aux)
> (__lexicographical_compare_aux): Add constexpr.
> * include/debug/vector (_Safe_vector, vector): Add constexpr.
> Omit safe iterator operations during constant evaluation.
> * testsuite/23_containers/vector/bool/capacity/constexpr.cc:
> Remove dg-xfail-if for debug mode.
> * testsuite/23_containers/vector/bool/cmp_c++20.cc: Likewise.
> * testsuite/23_containers/vector/bool/cons/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/bool/element_access/1.cc:
> Likewise.
> * testsuite/23_containers/vector/bool/element_access/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/bool/modifiers/assign/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/bool/modifiers/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/bool/modifiers/swap/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/capacity/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/cmp_c++20.cc: Likewise.
> * testsuite/23_containers/vector/cons/constexpr.cc: Likewise.
> * testsuite/23_containers/vector/data_access/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/element_access/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/modifiers/assign/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/modifiers/constexpr.cc:
> Likewise.
> * testsuite/23_containers/vector/modifiers/swap/constexpr.cc:
> Likewise.
> ---
> libstdc++-v3/include/bits/c++config | 9 -
> libstdc++-v3/include/bits/stl_algobase.h | 15 ++
> libstdc++-v3/include/debug/helper_functions.h | 1 +
> libstdc++-v3/include/debug/macros.h | 9 +-
> libstdc++-v3/include/debug/safe_base.h | 35 +++-
> libstdc++-v3/include/debug/safe_container.h | 15 +-
> libstdc++-v3/include/debug/safe_iterator.h | 186 +++++++++++++++---
> libstdc++-v3/include/debug/safe_iterator.tcc | 15 ++
> libstdc++-v3/include/debug/vector | 146 ++++++++++++--
> .../vector/bool/capacity/constexpr.cc | 1 -
> .../23_containers/vector/bool/cmp_c++20.cc | 1 -
> .../vector/bool/cons/constexpr.cc | 1 -
> .../vector/bool/element_access/1.cc | 1 -
> .../vector/bool/element_access/constexpr.cc | 1 -
> .../vector/bool/modifiers/assign/constexpr.cc | 1 -
> .../vector/bool/modifiers/constexpr.cc | 1 -
> .../vector/bool/modifiers/swap/constexpr.cc | 3 +-
> .../vector/capacity/constexpr.cc | 1 -
> .../23_containers/vector/cmp_c++20.cc | 1 -
> .../23_containers/vector/cons/constexpr.cc | 1 -
> .../vector/data_access/constexpr.cc | 1 -
> .../vector/element_access/constexpr.cc | 1 -
> .../vector/modifiers/assign/constexpr.cc | 1 -
> .../vector/modifiers/constexpr.cc | 1 -
> .../vector/modifiers/swap/constexpr.cc | 1 -
> 25 files changed, 369 insertions(+), 80 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/c++config
> b/libstdc++-v3/include/bits/c++config
> index 284d24d933f..13d416845c3 100644
> --- a/libstdc++-v3/include/bits/c++config
> +++ b/libstdc++-v3/include/bits/c++config
> @@ -565,15 +565,6 @@ namespace std
> # define _GLIBCXX_EXTERN_TEMPLATE -1
> #endif
>
> -
> -#if _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
> -# define __glibcxx_constexpr_assert(cond) \
> - if (std::__is_constant_evaluated() && !bool(cond)) \
> - __builtin_unreachable() /* precondition violation detected! */
> -#else
> -# define __glibcxx_constexpr_assert(unevaluated)
> -#endif
> -
> #undef _GLIBCXX_VERBOSE_ASSERT
>
> // Assert.
> diff --git a/libstdc++-v3/include/bits/stl_algobase.h
> b/libstdc++-v3/include/bits/stl_algobase.h
> index 01ca4496dfd..77d0ee7bcf5 100644
> --- a/libstdc++-v3/include/bits/stl_algobase.h
> +++ b/libstdc++-v3/include/bits/stl_algobase.h
> @@ -318,6 +318,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> { return __it; }
>
> template<typename _Ite, typename _Seq>
> + _GLIBCXX20_CONSTEXPR
> _Ite
> __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
> std::random_access_iterator_tag>&);
> @@ -545,6 +546,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
>
> template<bool _IsMove,
> typename _Ite, typename _Seq, typename _Cat, typename _OI>
> + _GLIBCXX20_CONSTEXPR
> _OI
> __copy_move_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&,
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&,
> @@ -552,6 +554,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
>
> template<bool _IsMove,
> typename _II, typename _Ite, typename _Seq, typename _Cat>
> + _GLIBCXX20_CONSTEXPR
> __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
> __copy_move_a(_II, _II,
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&);
> @@ -559,6 +562,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
> template<bool _IsMove,
> typename _IIte, typename _ISeq, typename _ICat,
> typename _OIte, typename _OSeq, typename _OCat>
> + _GLIBCXX20_CONSTEXPR
> ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
> __copy_move_a(const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>&,
> const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>&,
> @@ -812,6 +816,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
>
> template<bool _IsMove,
> typename _Ite, typename _Seq, typename _Cat, typename _OI>
> + _GLIBCXX20_CONSTEXPR
> _OI
> __copy_move_backward_a(
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&,
> @@ -820,6 +825,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
>
> template<bool _IsMove,
> typename _II, typename _Ite, typename _Seq, typename _Cat>
> + _GLIBCXX20_CONSTEXPR
> __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
> __copy_move_backward_a(_II, _II,
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&);
> @@ -827,6 +833,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
> template<bool _IsMove,
> typename _IIte, typename _ISeq, typename _ICat,
> typename _OIte, typename _OSeq, typename _OCat>
> + _GLIBCXX20_CONSTEXPR
> ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
> __copy_move_backward_a(
> const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>&,
> @@ -977,6 +984,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
> { std::__fill_a1(__first, __last, __value); }
>
> template<typename _Ite, typename _Seq, typename _Cat, typename _Tp>
> + _GLIBCXX20_CONSTEXPR
> void
> __fill_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&,
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&,
> @@ -1082,6 +1090,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
>
> template<typename _Ite, typename _Seq, typename _Cat, typename _Size,
> typename _Tp>
> + _GLIBCXX20_CONSTEXPR
> ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
> __fill_n_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&
> __first,
> _Size __n, const _Tp& __value,
> @@ -1230,18 +1239,21 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
> }
>
> template<typename _II1, typename _Seq1, typename _Cat1, typename _II2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __equal_aux(const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>&,
> const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>&,
> _II2);
>
> template<typename _II1, typename _II2, typename _Seq2, typename _Cat2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __equal_aux(_II1, _II1,
> const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>&);
>
> template<typename _II1, typename _Seq1, typename _Cat1,
> typename _II2, typename _Seq2, typename _Cat2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __equal_aux(const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>&,
> const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>&,
> @@ -1430,6 +1442,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
>
> template<typename _Iter1, typename _Seq1, typename _Cat1,
> typename _II2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __lexicographical_compare_aux(
> const ::__gnu_debug::_Safe_iterator<_Iter1, _Seq1, _Cat1>&,
> @@ -1438,6 +1451,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
>
> template<typename _II1,
> typename _Iter2, typename _Seq2, typename _Cat2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __lexicographical_compare_aux(
> _II1, _II1,
> @@ -1446,6 +1460,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
>
> template<typename _Iter1, typename _Seq1, typename _Cat1,
> typename _Iter2, typename _Seq2, typename _Cat2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __lexicographical_compare_aux(
> const ::__gnu_debug::_Safe_iterator<_Iter1, _Seq1, _Cat1>&,
> diff --git a/libstdc++-v3/include/debug/helper_functions.h
> b/libstdc++-v3/include/debug/helper_functions.h
> index 052b36b484c..4b76cb00f9a 100644
> --- a/libstdc++-v3/include/debug/helper_functions.h
> +++ b/libstdc++-v3/include/debug/helper_functions.h
> @@ -324,6 +324,7 @@ namespace __gnu_debug
>
> /* Remove debug mode safe iterator layer, if any. */
> template<typename _Iterator>
> + _GLIBCXX_CONSTEXPR
> inline _Iterator
> __unsafe(_Iterator __it)
> { return __it; }
> diff --git a/libstdc++-v3/include/debug/macros.h
> b/libstdc++-v3/include/debug/macros.h
> index 0fef0a006fc..4a3d0f2ea84 100644
> --- a/libstdc++-v3/include/debug/macros.h
> +++ b/libstdc++-v3/include/debug/macros.h
> @@ -38,15 +38,12 @@
> * the user error and where the error is reported.
> *
> */
> -#define _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func) \
> - if (__builtin_expect(!bool(_Cond), false)) \
> - __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func) \
> - ._ErrMsg._M_error()
>
> #define _GLIBCXX_DEBUG_VERIFY_AT_F(_Cond,_ErrMsg,_File,_Line,_Func) \
> do { \
> - __glibcxx_constexpr_assert(_Cond); \
> - _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func); \
> + if (__builtin_expect(!bool(_Cond), false)) \
> + __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func)
> \
> + ._ErrMsg._M_error(); \
> } while (false)
>
> #define _GLIBCXX_DEBUG_VERIFY_AT(_Cond,_ErrMsg,_File,_Line) \
> diff --git a/libstdc++-v3/include/debug/safe_base.h
> b/libstdc++-v3/include/debug/safe_base.h
> index 1dfa9f68b65..d9c17b52b48 100644
> --- a/libstdc++-v3/include/debug/safe_base.h
> +++ b/libstdc++-v3/include/debug/safe_base.h
> @@ -75,6 +75,7 @@ namespace __gnu_debug
>
> protected:
> /** Initializes the iterator and makes it singular. */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator_base()
> : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
> { }
> @@ -86,18 +87,31 @@ namespace __gnu_debug
> * 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)
> - { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); }
> + {
> + if (!std::__is_constant_evaluated())
> + this->_M_attach(const_cast<_Safe_sequence_base*>(__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. */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant)
> : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
> - { this->_M_attach(__x._M_sequence, __constant); }
> + {
> + if (!std::__is_constant_evaluated())
> + this->_M_attach(__x._M_sequence, __constant);
> + }
>
> - ~_Safe_iterator_base() { this->_M_detach(); }
> + _GLIBCXX20_CONSTEXPR
> + ~_Safe_iterator_base()
> + {
> + if (!std::__is_constant_evaluated())
> + this->_M_detach();
> + }
>
> /** For use in _Safe_iterator. */
> __gnu_cxx::__mutex&
> @@ -201,24 +215,34 @@ namespace __gnu_debug
>
> protected:
> // Initialize with a version number of 1 and no iterators
> + _GLIBCXX20_CONSTEXPR
> _Safe_sequence_base() _GLIBCXX_NOEXCEPT
> : _M_iterators(0), _M_const_iterators(0), _M_version(1)
> { }
>
> #if __cplusplus >= 201103L
> + _GLIBCXX20_CONSTEXPR
> _Safe_sequence_base(const _Safe_sequence_base&) noexcept
> : _Safe_sequence_base() { }
>
> // Move constructor swap iterators.
> + _GLIBCXX20_CONSTEXPR
> _Safe_sequence_base(_Safe_sequence_base&& __seq) noexcept
> : _Safe_sequence_base()
> - { _M_swap(__seq); }
> + {
> + if (!std::__is_constant_evaluated())
> + _M_swap(__seq);
> + }
> #endif
>
> /** Notify all iterators that reference this sequence that the
> sequence is being destroyed. */
> + _GLIBCXX20_CONSTEXPR
> ~_Safe_sequence_base()
> - { this->_M_detach_all(); }
> + {
> + if (!std::__is_constant_evaluated())
> + this->_M_detach_all();
> + }
>
> /** Detach all iterators, leaving them singular. */
> void
> @@ -244,6 +268,7 @@ namespace __gnu_debug
> * operation is complete all iterators that originally referenced
> * one container now reference the other container.
> */
> + _GLIBCXX20_CONSTEXPR
> void
> _M_swap(_Safe_sequence_base& __x) _GLIBCXX_USE_NOEXCEPT;
>
> diff --git a/libstdc++-v3/include/debug/safe_container.h
> b/libstdc++-v3/include/debug/safe_container.h
> index 0d8f64740b0..636156af9f5 100644
> --- a/libstdc++-v3/include/debug/safe_container.h
> +++ b/libstdc++-v3/include/debug/safe_container.h
> @@ -43,6 +43,7 @@ namespace __gnu_debug
> {
> typedef _SafeBase<_SafeContainer> _Base;
>
> + _GLIBCXX20_CONSTEXPR
> _SafeContainer&
> _M_cont() _GLIBCXX_NOEXCEPT
> { return *static_cast<_SafeContainer*>(this); }
> @@ -54,20 +55,23 @@ namespace __gnu_debug
> _Safe_container(_Safe_container&&) = default;
>
> private:
> + _GLIBCXX20_CONSTEXPR
> _Safe_container(_Safe_container&& __x, const _Alloc&, std::true_type)
> : _Safe_container(std::move(__x))
> { }
>
> + _GLIBCXX20_CONSTEXPR
> _Safe_container(_Safe_container&& __x, const _Alloc& __a,
> std::false_type)
> : _Safe_container()
> {
> if (__x._M_cont().get_allocator() == __a)
> _Base::_M_swap(__x);
> - else
> + else if (!std::__is_constant_evaluated())
> __x._M_invalidate_all();
> }
>
> protected:
> + _GLIBCXX20_CONSTEXPR
> _Safe_container(_Safe_container&& __x, const _Alloc& __a)
> : _Safe_container(std::move(__x), __a,
> typename
> std::allocator_traits<_Alloc>::is_always_equal{})
> @@ -75,17 +79,23 @@ namespace __gnu_debug
> #endif
>
> // Copy assignment invalidate all iterators.
> + _GLIBCXX20_CONSTEXPR
> _Safe_container&
> operator=(const _Safe_container&) _GLIBCXX_NOEXCEPT
> {
> - this->_M_invalidate_all();
> + if (!std::__is_constant_evaluated())
> + this->_M_invalidate_all();
> return *this;
> }
>
> #if __cplusplus >= 201103L
> + _GLIBCXX20_CONSTEXPR
> _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
> @@ -113,6 +123,7 @@ namespace __gnu_debug
> return *this;
> }
>
> + _GLIBCXX20_CONSTEXPR
> void
> _M_swap(_Safe_container& __x) noexcept
> {
> diff --git a/libstdc++-v3/include/debug/safe_iterator.h
> b/libstdc++-v3/include/debug/safe_iterator.h
> index 693192b3ea9..26f008982f8 100644
> --- a/libstdc++-v3/include/debug/safe_iterator.h
> +++ b/libstdc++-v3/include/debug/safe_iterator.h
> @@ -40,6 +40,7 @@
> #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()), \
> @@ -49,7 +50,8 @@
> _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, \
> @@ -131,9 +133,13 @@ namespace __gnu_debug
>
> struct _Unchecked { };
>
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(const _Safe_iterator& __x, _Unchecked) _GLIBCXX_NOEXCEPT
> : _Iter_base(__x.base()), _Safe_base()
> - { _M_attach(__x._M_sequence); }
> + {
> + if (!std::__is_constant_evaluated())
> + _M_attach(__x._M_sequence);
> + }
>
> public:
> typedef _Iterator iterator_type;
> @@ -148,6 +154,7 @@ namespace __gnu_debug
> #endif
>
> /// @post the iterator is singular and unattached
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { }
>
> /**
> @@ -157,6 +164,7 @@ namespace __gnu_debug
> * @pre @p seq is not NULL
> * @post this is not singular
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
> _GLIBCXX_NOEXCEPT
> : _Iter_base(__i), _Safe_base(__seq, _S_constant())
> @@ -165,9 +173,13 @@ namespace __gnu_debug
> /**
> * @brief Copy construction.
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
> : _Iter_base(__x.base()), _Safe_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()
> @@ -183,9 +195,16 @@ namespace __gnu_debug
> * @brief Move construction.
> * @post __x is singular and unattached
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(_Safe_iterator&& __x) noexcept
> : _Iter_base()
> {
> + 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)
> @@ -203,6 +222,7 @@ namespace __gnu_debug
> * constant iterator.
> */
> template<typename _MutableIterator>
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(
> const _Safe_iterator<_MutableIterator, _Sequence,
> typename __gnu_cxx::__enable_if<_IsConstant::__value &&
> @@ -211,6 +231,9 @@ namespace __gnu_debug
> _GLIBCXX_NOEXCEPT
> : _Iter_base(__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()
> @@ -224,9 +247,16 @@ namespace __gnu_debug
> /**
> * @brief Copy assignment.
> */
> + _GLIBCXX20_CONSTEXPR
> _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()
> @@ -256,9 +286,16 @@ namespace __gnu_debug
> * @brief Move assignment.
> * @post __x is singular and unattached
> */
> + _GLIBCXX20_CONSTEXPR
> _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)
> @@ -292,12 +329,16 @@ namespace __gnu_debug
> * @pre iterator is dereferenceable
> */
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> reference
> operator*() const _GLIBCXX_NOEXCEPT
> {
> - _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
> - _M_message(__msg_bad_deref)
> - ._M_iterator(*this, "this"));
> + if (!std::__is_constant_evaluated())
> + {
> + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
> + _M_message(__msg_bad_deref)
> + ._M_iterator(*this, "this"));
> + }
> return *base();
> }
>
> @@ -306,12 +347,16 @@ namespace __gnu_debug
> * @pre iterator is dereferenceable
> */
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> pointer
> operator->() const _GLIBCXX_NOEXCEPT
> {
> - _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
> - _M_message(__msg_bad_deref)
> - ._M_iterator(*this, "this"));
> + if (!std::__is_constant_evaluated())
> + {
> + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
> + _M_message(__msg_bad_deref)
> + ._M_iterator(*this, "this"));
> + }
> return base().operator->();
> }
>
> @@ -320,9 +365,16 @@ namespace __gnu_debug
> * @brief Iterator preincrement
> * @pre iterator is incrementable
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator&
> operator++() _GLIBCXX_NOEXCEPT
> {
> + if (std::__is_constant_evaluated())
> + {
> + ++base();
> + return *this;
> + }
> +
> _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
> _M_message(__msg_bad_inc)
> ._M_iterator(*this, "this"));
> @@ -335,12 +387,16 @@ namespace __gnu_debug
> * @brief Iterator postincrement
> * @pre iterator is incrementable
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator
> operator++(int) _GLIBCXX_NOEXCEPT
> {
> - _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
> - _M_message(__msg_bad_inc)
> - ._M_iterator(*this, "this"));
> + if (!std::__is_constant_evaluated())
> + {
> + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
> + _M_message(__msg_bad_inc)
> + ._M_iterator(*this, "this"));
> + }
> _Safe_iterator __ret(*this, _Unchecked());
> ++*this;
> return __ret;
> @@ -356,9 +412,11 @@ namespace __gnu_debug
> /**
> * @brief Return the underlying iterator
> */
> + _GLIBCXX20_CONSTEXPR
> _Iterator&
> base() _GLIBCXX_NOEXCEPT { return *this; }
>
> + _GLIBCXX20_CONSTEXPR
> const _Iterator&
> base() const _GLIBCXX_NOEXCEPT { return *this; }
>
> @@ -366,6 +424,7 @@ namespace __gnu_debug
> * @brief Conversion to underlying non-debug iterator to allow
> * better interaction with non-debug containers.
> */
> + _GLIBCXX20_CONSTEXPR
> operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; }
>
> /** Attach iterator to the given sequence. */
> @@ -440,6 +499,7 @@ namespace __gnu_debug
> _M_get_distance_to_end() const;
>
> /// Is this iterator equal to the sequence's begin() iterator?
> + _GLIBCXX20_CONSTEXPR
> bool
> _M_is_begin() const
> { return base() == _M_get_sequence()->_M_base().begin(); }
> @@ -466,6 +526,7 @@ namespace __gnu_debug
> typedef _Safe_iterator<_Iterator, _Sequence, iterator_category> _Self;
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> friend bool
> operator==(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
> {
> @@ -475,6 +536,7 @@ namespace __gnu_debug
>
> template<typename _IteR>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> friend bool
> operator==(const _Self& __lhs,
> const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
> @@ -518,6 +580,7 @@ namespace __gnu_debug
>
> typedef typename _Safe_base::_Unchecked _Unchecked;
>
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(const _Safe_iterator& __x,
> _Unchecked __unchecked) _GLIBCXX_NOEXCEPT
> : _Safe_base(__x, __unchecked)
> @@ -525,6 +588,7 @@ namespace __gnu_debug
>
> public:
> /// @post the iterator is singular and unattached
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator() _GLIBCXX_NOEXCEPT { }
>
> /**
> @@ -534,6 +598,7 @@ namespace __gnu_debug
> * @pre @p seq is not NULL
> * @post this is not singular
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
> _GLIBCXX_NOEXCEPT
> : _Safe_base(__i, __seq)
> @@ -542,12 +607,14 @@ namespace __gnu_debug
> /**
> * @brief Copy construction.
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
> : _Safe_base(__x)
> { }
>
> #if __cplusplus >= 201103L
> /** @brief Move construction. */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(_Safe_iterator&&) = default;
> #endif
>
> @@ -556,6 +623,7 @@ namespace __gnu_debug
> * constant iterator.
> */
> template<typename _MutableIterator>
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(
> const _Safe_iterator<_MutableIterator, _Sequence,
> typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value
> &&
> @@ -588,6 +656,7 @@ namespace __gnu_debug
> * @brief Iterator preincrement
> * @pre iterator is incrementable
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator&
> operator++() _GLIBCXX_NOEXCEPT
> {
> @@ -615,9 +684,16 @@ namespace __gnu_debug
> * @brief Iterator predecrement
> * @pre iterator is decrementable
> */
> + _GLIBCXX20_CONSTEXPR
> _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"));
> @@ -663,6 +739,8 @@ namespace __gnu_debug
> std::random_access_iterator_tag> _OtherSelf;
>
> typedef typename _Safe_base::_Unchecked _Unchecked;
> +
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(const _Safe_iterator& __x,
> _Unchecked __unchecked) _GLIBCXX_NOEXCEPT
> : _Safe_base(__x, __unchecked)
> @@ -673,6 +751,7 @@ namespace __gnu_debug
> typedef typename _Safe_base::reference reference;
>
> /// @post the iterator is singular and unattached
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator() _GLIBCXX_NOEXCEPT { }
>
> /**
> @@ -682,6 +761,7 @@ namespace __gnu_debug
> * @pre @p seq is not NULL
> * @post this is not singular
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
> _GLIBCXX_NOEXCEPT
> : _Safe_base(__i, __seq)
> @@ -690,6 +770,7 @@ namespace __gnu_debug
> /**
> * @brief Copy construction.
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
> : _Safe_base(__x)
> { }
> @@ -704,6 +785,7 @@ namespace __gnu_debug
> * constant iterator.
> */
> template<typename _MutableIterator>
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator(
> const _Safe_iterator<_MutableIterator, _Sequence,
> typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value
> &&
> @@ -742,6 +824,7 @@ namespace __gnu_debug
> * @brief Iterator preincrement
> * @pre iterator is incrementable
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator&
> operator++() _GLIBCXX_NOEXCEPT
> {
> @@ -753,12 +836,16 @@ namespace __gnu_debug
> * @brief Iterator postincrement
> * @pre iterator is incrementable
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator
> operator++(int) _GLIBCXX_NOEXCEPT
> {
> - _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
> - _M_message(__msg_bad_inc)
> - ._M_iterator(*this, "this"));
> + if (!std::__is_constant_evaluated())
> + {
> + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
> + _M_message(__msg_bad_inc)
> + ._M_iterator(*this, "this"));
> + }
> _Safe_iterator __ret(*this, _Unchecked());
> ++*this;
> return __ret;
> @@ -769,6 +856,7 @@ namespace __gnu_debug
> * @brief Iterator predecrement
> * @pre iterator is decrementable
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator&
> operator--() _GLIBCXX_NOEXCEPT
> {
> @@ -780,12 +868,16 @@ namespace __gnu_debug
> * @brief Iterator postdecrement
> * @pre iterator is decrementable
> */
> + _GLIBCXX20_CONSTEXPR
> _Safe_iterator
> operator--(int) _GLIBCXX_NOEXCEPT
> {
> - _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
> - _M_message(__msg_bad_dec)
> - ._M_iterator(*this, "this"));
> + if (!std::__is_constant_evaluated())
> + {
> + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
> + _M_message(__msg_bad_dec)
> + ._M_iterator(*this, "this"));
> + }
> _Safe_iterator __ret(*this, _Unchecked());
> --*this;
> return __ret;
> @@ -793,19 +885,30 @@ namespace __gnu_debug
>
> // ------ Random access iterator requirements ------
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> reference
> operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
> {
> - _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));
> + 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));
> + }
> return this->base()[__n];
> }
>
> + _GLIBCXX20_CONSTEXPR
> _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));
> @@ -814,9 +917,16 @@ namespace __gnu_debug
> return *this;
> }
>
> + _GLIBCXX20_CONSTEXPR
> _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));
> @@ -827,6 +937,7 @@ namespace __gnu_debug
>
> #if __cpp_lib_three_way_comparison
> [[nodiscard]]
> + _GLIBCXX20_CONSTEXPR
> friend auto
> operator<=>(const _Self& __lhs, const _Self& __rhs) noexcept
> {
> @@ -835,6 +946,7 @@ namespace __gnu_debug
> }
>
> [[nodiscard]]
> + _GLIBCXX20_CONSTEXPR
> friend auto
> operator<=>(const _Self& __lhs, const _OtherSelf& __rhs) noexcept
> {
> @@ -912,6 +1024,7 @@ namespace __gnu_debug
> // operators but also operator- must accept mixed
> iterator/const_iterator
> // parameters.
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> friend difference_type
> operator-(const _Self& __lhs, const _OtherSelf& __rhs)
> _GLIBCXX_NOEXCEPT
> {
> @@ -920,6 +1033,7 @@ namespace __gnu_debug
> }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> friend difference_type
> operator-(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
> {
> @@ -928,32 +1042,44 @@ namespace __gnu_debug
> }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> friend _Self
> operator+(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
> {
> - _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
> - _M_message(__msg_advance_oob)
> - ._M_iterator(__x)._M_integer(__n));
> + if (!std::__is_constant_evaluated())
> + {
> + _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);
> }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> friend _Self
> operator+(difference_type __n, const _Self& __x) _GLIBCXX_NOEXCEPT
> {
> - _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
> - _M_message(__msg_advance_oob)
> - ._M_iterator(__x)._M_integer(__n));
> + if (!std::__is_constant_evaluated())
> + {
> + _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);
> }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> friend _Self
> operator-(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
> {
> - _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
> - _M_message(__msg_retreat_oob)
> - ._M_iterator(__x)._M_integer(__n));
> + if (!std::__is_constant_evaluated())
> + {
> + _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);
> }
> };
> diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc
> b/libstdc++-v3/include/debug/safe_iterator.tcc
> index 170229ad2f1..0bb3dd017b9 100644
> --- a/libstdc++-v3/include/debug/safe_iterator.tcc
> +++ b/libstdc++-v3/include/debug/safe_iterator.tcc
> @@ -236,6 +236,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
> _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<typename _Ite, typename _Seq>
> + _GLIBCXX20_CONSTEXPR
> _Ite
> __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
> std::random_access_iterator_tag>& __it)
> @@ -243,6 +244,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<bool _IsMove,
> typename _Ite, typename _Seq, typename _Cat, typename _OI>
> + _GLIBCXX20_CONSTEXPR
> _OI
> __copy_move_a(
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
> @@ -262,6 +264,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<bool _IsMove,
> typename _II, typename _Ite, typename _Seq, typename _Cat>
> + _GLIBCXX20_CONSTEXPR
> __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
> __copy_move_a(_II __first, _II __last,
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
> @@ -282,6 +285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> template<bool _IsMove,
> typename _IIte, typename _ISeq, typename _ICat,
> typename _OIte, typename _OSeq, typename _OCat>
> + _GLIBCXX20_CONSTEXPR
> ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
> __copy_move_a(
> const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
> @@ -310,6 +314,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<bool _IsMove,
> typename _Ite, typename _Seq, typename _Cat, typename _OI>
> + _GLIBCXX20_CONSTEXPR
> _OI
> __copy_move_backward_a(
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&
> __first,
> @@ -329,6 +334,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<bool _IsMove,
> typename _II, typename _Ite, typename _Seq, typename _Cat>
> + _GLIBCXX20_CONSTEXPR
> __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
> __copy_move_backward_a(_II __first, _II __last,
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
> @@ -350,6 +356,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> template<bool _IsMove,
> typename _IIte, typename _ISeq, typename _ICat,
> typename _OIte, typename _OSeq, typename _OCat>
> + _GLIBCXX20_CONSTEXPR
> ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
> __copy_move_backward_a(
> const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
> @@ -377,6 +384,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> }
>
> template<typename _Ite, typename _Seq, typename _Cat, typename _Tp>
> + _GLIBCXX20_CONSTEXPR
> void
> __fill_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
> const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
> @@ -393,6 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<typename _Ite, typename _Seq, typename _Cat, typename _Size,
> typename _Tp>
> + _GLIBCXX20_CONSTEXPR
> ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
> __fill_n_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&
> __first,
> _Size __n, const _Tp& __value,
> @@ -415,6 +424,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> }
>
> template<typename _II1, typename _Seq1, typename _Cat1, typename _II2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __equal_aux(
> const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
> @@ -432,6 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> }
>
> template<typename _II1, typename _II2, typename _Seq2, typename _Cat2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __equal_aux(_II1 __first1, _II1 __last1,
> const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
> @@ -449,6 +460,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<typename _II1, typename _Seq1, typename _Cat1,
> typename _II2, typename _Seq2, typename _Cat2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __equal_aux(
> const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
> @@ -473,6 +485,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<typename _Ite1, typename _Seq1, typename _Cat1,
> typename _II2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __lexicographical_compare_aux(
> const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
> @@ -493,6 +506,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<typename _II1,
> typename _Ite2, typename _Seq2, typename _Cat2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __lexicographical_compare_aux(
> _II1 __first1, _II1 __last1,
> @@ -513,6 +527,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> template<typename _Ite1, typename _Seq1, typename _Cat1,
> typename _Ite2, typename _Seq2, typename _Cat2>
> + _GLIBCXX20_CONSTEXPR
> bool
> __lexicographical_compare_aux(
> const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
> diff --git a/libstdc++-v3/include/debug/vector
> b/libstdc++-v3/include/debug/vector
> index ed462caf936..124ae6da1c1 100644
> --- a/libstdc++-v3/include/debug/vector
> +++ b/libstdc++-v3/include/debug/vector
> @@ -55,22 +55,27 @@ namespace __gnu_debug
> {
> typedef typename _BaseSequence::size_type size_type;
>
> + _GLIBCXX20_CONSTEXPR
> const _SafeSequence&
> _M_seq() const { return *static_cast<const _SafeSequence*>(this); }
>
> protected:
> + _GLIBCXX20_CONSTEXPR
> _Safe_vector() _GLIBCXX_NOEXCEPT
> : _M_guaranteed_capacity(0)
> { _M_update_guaranteed_capacity(); }
>
> + _GLIBCXX20_CONSTEXPR
> _Safe_vector(const _Safe_vector&) _GLIBCXX_NOEXCEPT
> : _M_guaranteed_capacity(0)
> { _M_update_guaranteed_capacity(); }
>
> + _GLIBCXX20_CONSTEXPR
> _Safe_vector(size_type __n) _GLIBCXX_NOEXCEPT
> : _M_guaranteed_capacity(__n)
> { }
>
> + _GLIBCXX20_CONSTEXPR
> _Safe_vector&
> operator=(const _Safe_vector&) _GLIBCXX_NOEXCEPT
> {
> @@ -79,10 +84,12 @@ namespace __gnu_debug
> }
>
> #if __cplusplus >= 201103L
> + _GLIBCXX20_CONSTEXPR
> _Safe_vector(_Safe_vector&& __x) noexcept
> : _Safe_vector()
> { __x._M_guaranteed_capacity = 0; }
>
> + _GLIBCXX20_CONSTEXPR
> _Safe_vector&
> operator=(_Safe_vector&& __x) noexcept
> {
> @@ -98,6 +105,7 @@ namespace __gnu_debug
> _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
> { return __elements > _M_seq().capacity(); }
>
> + _GLIBCXX20_CONSTEXPR
> void
> _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
> {
> @@ -172,15 +180,18 @@ namespace __debug
> vector() = default;
> #endif
>
> + _GLIBCXX20_CONSTEXPR
> explicit
> vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
> : _Base(__a) { }
>
> #if __cplusplus >= 201103L
> + _GLIBCXX20_CONSTEXPR
> explicit
> vector(size_type __n, const _Allocator& __a = _Allocator())
> : _Base(__n, __a), _Safe_vector(__n) { }
>
> + _GLIBCXX20_CONSTEXPR
> vector(size_type __n, const __type_identity_t<_Tp>& __value,
> const _Allocator& __a = _Allocator())
> : _Base(__n, __value, __a) { }
> @@ -197,10 +208,11 @@ namespace __debug
> #else
> template<class _InputIterator>
> #endif
> + _GLIBCXX20_CONSTEXPR
> vector(_InputIterator __first, _InputIterator __last,
> const _Allocator& __a = _Allocator())
> - : _Base(__gnu_debug::__base(
> - __glibcxx_check_valid_constructor_range(__first, __last)),
> + : _Base(__gnu_debug::__base(std::__is_constant_evaluated() ? __first
> + : __glibcxx_check_valid_constructor_range(__first, __last)),
> __gnu_debug::__base(__last), __a) { }
>
> #if __cplusplus < 201103L
> @@ -212,9 +224,11 @@ namespace __debug
> vector(const vector&) = default;
> vector(vector&&) = default;
>
> + _GLIBCXX20_CONSTEXPR
> vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
> : _Base(__x, __a) { }
>
> + _GLIBCXX20_CONSTEXPR
> vector(vector&& __x, const __type_identity_t<allocator_type>& __a)
> noexcept(
> std::is_nothrow_constructible<_Base,
> @@ -223,6 +237,7 @@ namespace __debug
> _Base(std::move(__x), __a),
> _Safe_vector(std::move(__x)) { }
>
> + _GLIBCXX20_CONSTEXPR
> vector(initializer_list<value_type> __l,
> const allocator_type& __a = allocator_type())
> : _Base(__l, __a) { }
> @@ -231,6 +246,7 @@ namespace __debug
> #endif
>
> /// Construction from a normal-mode vector
> + _GLIBCXX20_CONSTEXPR
> vector(_Base_ref __x)
> : _Base(__x._M_ref) { }
>
> @@ -241,12 +257,16 @@ namespace __debug
> vector&
> operator=(vector&&) = default;
>
> + _GLIBCXX20_CONSTEXPR
> vector&
> operator=(initializer_list<value_type> __l)
> {
> _Base::operator=(__l);
> - this->_M_invalidate_all();
> - this->_M_update_guaranteed_capacity();
> + if (!std::__is_constant_evaluated())
> + {
> + this->_M_invalidate_all();
> + this->_M_update_guaranteed_capacity();
> + }
> return *this;
> }
> #endif
> @@ -257,9 +277,14 @@ namespace __debug
> #else
> template<typename _InputIterator>
> #endif
> + _GLIBCXX20_CONSTEXPR
> 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);
>
> @@ -273,21 +298,29 @@ namespace __debug
> this->_M_update_guaranteed_capacity();
> }
>
> + _GLIBCXX20_CONSTEXPR
> void
> assign(size_type __n, const _Tp& __u)
> {
> _Base::assign(__n, __u);
> - this->_M_invalidate_all();
> - this->_M_update_guaranteed_capacity();
> + if (!std::__is_constant_evaluated())
> + {
> + this->_M_invalidate_all();
> + this->_M_update_guaranteed_capacity();
> + }
> }
>
> #if __cplusplus >= 201103L
> + _GLIBCXX20_CONSTEXPR
> void
> assign(initializer_list<value_type> __l)
> {
> _Base::assign(__l);
> - this->_M_invalidate_all();
> - this->_M_update_guaranteed_capacity();
> + if (!std::__is_constant_evaluated())
> + {
> + this->_M_invalidate_all();
> + this->_M_update_guaranteed_capacity();
> + }
> }
> #endif
>
> @@ -295,62 +328,74 @@ namespace __debug
>
> // iterators:
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> iterator
> begin() _GLIBCXX_NOEXCEPT
> { return iterator(_Base::begin(), this); }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> const_iterator
> begin() const _GLIBCXX_NOEXCEPT
> { return const_iterator(_Base::begin(), this); }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> iterator
> end() _GLIBCXX_NOEXCEPT
> { return iterator(_Base::end(), this); }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> const_iterator
> end() const _GLIBCXX_NOEXCEPT
> { return const_iterator(_Base::end(), this); }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> reverse_iterator
> rbegin() _GLIBCXX_NOEXCEPT
> { return reverse_iterator(end()); }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> const_reverse_iterator
> rbegin() const _GLIBCXX_NOEXCEPT
> { return const_reverse_iterator(end()); }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> reverse_iterator
> rend() _GLIBCXX_NOEXCEPT
> { return reverse_iterator(begin()); }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> const_reverse_iterator
> rend() const _GLIBCXX_NOEXCEPT
> { return const_reverse_iterator(begin()); }
>
> #if __cplusplus >= 201103L
> [[__nodiscard__]]
> + _GLIBCXX20_CONSTEXPR
> const_iterator
> cbegin() const noexcept
> { return const_iterator(_Base::begin(), this); }
>
> [[__nodiscard__]]
> + _GLIBCXX20_CONSTEXPR
> const_iterator
> cend() const noexcept
> { return const_iterator(_Base::end(), this); }
>
> [[__nodiscard__]]
> + _GLIBCXX20_CONSTEXPR
> const_reverse_iterator
> crbegin() const noexcept
> { return const_reverse_iterator(end()); }
>
> [[__nodiscard__]]
> + _GLIBCXX20_CONSTEXPR
> const_reverse_iterator
> crend() const noexcept
> { return const_reverse_iterator(begin()); }
> @@ -361,9 +406,13 @@ namespace __debug
> using _Base::max_size;
>
> #if __cplusplus >= 201103L
> + _GLIBCXX20_CONSTEXPR
> 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);
> @@ -373,9 +422,13 @@ namespace __debug
> this->_M_update_guaranteed_capacity();
> }
>
> + _GLIBCXX20_CONSTEXPR
> 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);
> @@ -399,9 +452,13 @@ namespace __debug
> #endif
>
> #if __cplusplus >= 201103L
> + _GLIBCXX20_CONSTEXPR
> 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();
> @@ -411,9 +468,13 @@ namespace __debug
> #endif
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> size_type
> capacity() const _GLIBCXX_NOEXCEPT
> {
> + if (std::__is_constant_evaluated())
> + return _Base::capacity();
> +
> #ifdef _GLIBCXX_DEBUG_PEDANTIC
> return this->_M_guaranteed_capacity;
> #else
> @@ -423,9 +484,13 @@ namespace __debug
>
> using _Base::empty;
>
> + _GLIBCXX20_CONSTEXPR
> 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)
> @@ -436,6 +501,7 @@ namespace __debug
>
> // element access:
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> reference
> operator[](size_type __n) _GLIBCXX_NOEXCEPT
> {
> @@ -444,6 +510,7 @@ namespace __debug
> }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> const_reference
> operator[](size_type __n) const _GLIBCXX_NOEXCEPT
> {
> @@ -454,6 +521,7 @@ namespace __debug
> using _Base::at;
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> reference
> front() _GLIBCXX_NOEXCEPT
> {
> @@ -462,6 +530,7 @@ namespace __debug
> }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> const_reference
> front() const _GLIBCXX_NOEXCEPT
> {
> @@ -470,6 +539,7 @@ namespace __debug
> }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> reference
> back() _GLIBCXX_NOEXCEPT
> {
> @@ -478,6 +548,7 @@ namespace __debug
> }
>
> _GLIBCXX_NODISCARD
> + _GLIBCXX20_CONSTEXPR
> const_reference
> back() const _GLIBCXX_NOEXCEPT
> {
> @@ -490,9 +561,13 @@ namespace __debug
> using _Base::data;
>
> // 23.2.4.3 modifiers:
> + _GLIBCXX20_CONSTEXPR
> 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)
> @@ -502,12 +577,14 @@ namespace __debug
>
> #if __cplusplus >= 201103L
> template<typename _Up = _Tp>
> + _GLIBCXX20_CONSTEXPR
> typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
> void>::__type
> push_back(_Tp&& __x)
> { emplace_back(std::move(__x)); }
>
> template<typename... _Args>
> + _GLIBCXX20_CONSTEXPR
> #if __cplusplus > 201402L
> reference
> #else
> @@ -515,6 +592,9 @@ 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)
> @@ -526,19 +606,29 @@ namespace __debug
> }
> #endif
>
> + _GLIBCXX20_CONSTEXPR
> void
> pop_back() _GLIBCXX_NOEXCEPT
> {
> - __glibcxx_check_nonempty();
> - this->_M_invalidate_if(_Equal(--_Base::end()));
> + if (!std::__is_constant_evaluated())
> + {
> + __glibcxx_check_nonempty();
> + this->_M_invalidate_if(_Equal(--_Base::end()));
> + }
> _Base::pop_back();
> }
>
> #if __cplusplus >= 201103L
> template<typename... _Args>
> + _GLIBCXX20_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);
> bool __realloc = this->_M_requires_reallocation(this->size() + 1);
> difference_type __offset = __position.base() - _Base::cbegin();
> @@ -553,6 +643,7 @@ namespace __debug
> }
> #endif
>
> + _GLIBCXX20_CONSTEXPR
> iterator
> #if __cplusplus >= 201103L
> insert(const_iterator __position, const _Tp& __x)
> @@ -560,6 +651,9 @@ 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();
> @@ -574,20 +668,26 @@ namespace __debug
>
> #if __cplusplus >= 201103L
> template<typename _Up = _Tp>
> + _GLIBCXX20_CONSTEXPR
> typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
> iterator>::__type
> insert(const_iterator __position, _Tp&& __x)
> { return emplace(__position, std::move(__x)); }
>
> + _GLIBCXX20_CONSTEXPR
> iterator
> insert(const_iterator __position, initializer_list<value_type> __l)
> { return this->insert(__position, __l.begin(), __l.end()); }
> #endif
>
> #if __cplusplus >= 201103L
> + _GLIBCXX20_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);
> bool __realloc = this->_M_requires_reallocation(this->size() + __n);
> difference_type __offset = __position.base() - _Base::cbegin();
> @@ -618,10 +718,16 @@ namespace __debug
> #if __cplusplus >= 201103L
> template<class _InputIterator,
> typename = std::_RequireInputIter<_InputIterator>>
> + _GLIBCXX20_CONSTEXPR
> iterator
> 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);
>
> @@ -673,6 +779,7 @@ namespace __debug
> }
> #endif
>
> + _GLIBCXX20_CONSTEXPR
> iterator
> #if __cplusplus >= 201103L
> erase(const_iterator __position)
> @@ -680,6 +787,9 @@ 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());
> @@ -687,6 +797,7 @@ namespace __debug
> return iterator(__res, this);
> }
>
> + _GLIBCXX20_CONSTEXPR
> iterator
> #if __cplusplus >= 201103L
> erase(const_iterator __first, const_iterator __last)
> @@ -694,6 +805,9 @@ 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);
> @@ -714,25 +828,31 @@ namespace __debug
> #endif
> }
>
> + _GLIBCXX20_CONSTEXPR
> void
> swap(vector& __x)
> _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
> {
> - _Safe::_M_swap(__x);
> + if (!std::__is_constant_evaluated())
> + _Safe::_M_swap(__x);
> _Base::swap(__x);
> std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
> }
>
> + _GLIBCXX20_CONSTEXPR
> void
> clear() _GLIBCXX_NOEXCEPT
> {
> _Base::clear();
> - this->_M_invalidate_all();
> + if (!std::__is_constant_evaluated())
> + this->_M_invalidate_all();
> }
>
> + _GLIBCXX20_CONSTEXPR
> _Base&
> _M_base() _GLIBCXX_NOEXCEPT { return *this; }
>
> + _GLIBCXX20_CONSTEXPR
> const _Base&
> _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
>
> @@ -746,6 +866,7 @@ namespace __debug
> };
>
> template<typename _Tp, typename _Alloc>
> + _GLIBCXX20_CONSTEXPR
> inline bool
> operator==(const vector<_Tp, _Alloc>& __lhs,
> const vector<_Tp, _Alloc>& __rhs)
> @@ -789,6 +910,7 @@ namespace __debug
> #endif // three-way comparison
>
> template<typename _Tp, typename _Alloc>
> + _GLIBCXX20_CONSTEXPR
> inline void
> swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
> _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/constexpr.cc
> index d44e9d97b46..534128c487e 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/cmp_c++20.cc
> b/libstdc++-v3/testsuite/23_containers/vector/bool/cmp_c++20.cc
> index 66197e0aa29..e852c388903 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/bool/cmp_c++20.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/cmp_c++20.cc
> @@ -16,7 +16,6 @@
> // <http://www.gnu.org/licenses/>.
>
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/bool/cons/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/bool/cons/constexpr.cc
> index 0e0c1e1c5ec..88d99fe682f 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/bool/cons/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/cons/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/bool/element_access/1.cc
> b/libstdc++-v3/testsuite/23_containers/vector/bool/element_access/1.cc
> index 2a430845058..e7d710829e1 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/bool/element_access/1.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/element_access/1.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++23 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/bool/element_access/constexpr.cc
>
> b/libstdc++-v3/testsuite/23_containers/vector/bool/element_access/constexpr.cc
> index 5b8ca94e78f..d6b657e0161 100644
> ---
> a/libstdc++-v3/testsuite/23_containers/vector/bool/element_access/constexpr.cc
> +++
> b/libstdc++-v3/testsuite/23_containers/vector/bool/element_access/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/constexpr.cc
>
> b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/constexpr.cc
> index 3ad7dda88a9..31a6793f7ff 100644
> ---
> a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/constexpr.cc
> +++
> b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/constexpr.cc
> index 22a4df5e370..0e37f9aa786 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/constexpr.cc
>
> b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/constexpr.cc
> index 624ff96a9e9..d2a0218a109 100644
> ---
> a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/constexpr.cc
> +++
> b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <utility>
> @@ -49,6 +48,7 @@ test_member_swap()
>
> static_assert(test_member_swap());
>
> +#ifndef _GLIBCXX_DEBUG
> constexpr bool
> test_reference_swap()
> {
> @@ -63,3 +63,4 @@ test_reference_swap()
> }
>
> static_assert(test_reference_swap());
> +#endif
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/capacity/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/capacity/constexpr.cc
> index 018a4792891..c331dbd5e57 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/capacity/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git a/libstdc++-v3/testsuite/23_containers/vector/cmp_c++20.cc
> b/libstdc++-v3/testsuite/23_containers/vector/cmp_c++20.cc
> index 72c5c6cd7f9..63cb92c0edf 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/cmp_c++20.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/cmp_c++20.cc
> @@ -16,7 +16,6 @@
> // <http://www.gnu.org/licenses/>.
>
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/cons/constexpr.cc
> index 7bf86511240..fa78676b300 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/cons/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/constexpr.cc
> @@ -1,6 +1,5 @@
> // { dg-do compile { target c++20 } }
> // { dg-add-options no_pch }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/data_access/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/data_access/constexpr.cc
> index f5b601a44f4..142050e8f03 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/data_access/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/data_access/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc
> index 60c66dcc647..ee93d2fd95e 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/constexpr.cc
> index cca20f4291c..41fc8d9696e 100644
> ---
> a/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/constexpr.cc
> +++
> b/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/modifiers/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/modifiers/constexpr.cc
> index 766e3a7690f..4aa1f1f67b7 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/modifiers/swap/constexpr.cc
> b/libstdc++-v3/testsuite/23_containers/vector/modifiers/swap/constexpr.cc
> index 45b3986beca..77d2a518d69 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/swap/constexpr.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/swap/constexpr.cc
> @@ -1,5 +1,4 @@
> // { dg-do compile { target c++20 } }
> -// { dg-xfail-if "not supported" { debug_mode } }
>
> #include <vector>
> #include <utility>
> --
> 2.43.0
>