On Wed, 6 Dec 2023, Jonathan Wakely wrote: > Any comments on this approach? > > -- >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.
AFAICT these C++20 test failures are really due to the variable definition of non-literal type 381 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); which were prohibited in a constexpr function (even if that code was never executed) until C++23's P2242R3. We can use an immediately invoked lambda to work around this: 381 [this] { 382 __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); 383 ++base(); 384 }(); 385 return *this; > > 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; With -Wsystem-headers on some ranges tests I get: /gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/safe_base.h:273:5: warning: inline function ‘constexpr void __gnu_debug::_Safe_sequence_base::_M_swap(__gnu_debug::_Safe_sequence_base&)’ used but never defined 273 | _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 > >