libstdc++: Make __gnu_debug::vector usable in constant expressions [PR109536]
commit7d00a59229ee17af009a3c6c6208b0611740ed49
authorJonathan Wakely <jwakely@redhat.com>
Wed, 6 Dec 2023 13:39:52 +0000 (6 13:39 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 14 Dec 2023 16:07:48 +0000 (14 16:07 +0000)
tree63bdd05fd14060189f9feba929f11e38fd4652ea
parent4e9b2c94e45f5991a472fb639fb2baa6aa42b76b
libstdc++: Make __gnu_debug::vector usable in constant expressions [PR109536]

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 called 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.
* testsuite/23_containers/vector/cons/destructible_debug_neg.cc:
Adjust dg-error line number.
26 files changed:
libstdc++-v3/include/bits/c++config
libstdc++-v3/include/bits/stl_algobase.h
libstdc++-v3/include/debug/helper_functions.h
libstdc++-v3/include/debug/macros.h
libstdc++-v3/include/debug/safe_base.h
libstdc++-v3/include/debug/safe_container.h
libstdc++-v3/include/debug/safe_iterator.h
libstdc++-v3/include/debug/safe_iterator.tcc
libstdc++-v3/include/debug/vector
libstdc++-v3/testsuite/23_containers/vector/bool/capacity/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/bool/cmp_c++20.cc
libstdc++-v3/testsuite/23_containers/vector/bool/cons/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/bool/element_access/1.cc
libstdc++-v3/testsuite/23_containers/vector/bool/element_access/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/capacity/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/cmp_c++20.cc
libstdc++-v3/testsuite/23_containers/vector/cons/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/cons/destructible_debug_neg.cc
libstdc++-v3/testsuite/23_containers/vector/data_access/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/modifiers/constexpr.cc
libstdc++-v3/testsuite/23_containers/vector/modifiers/swap/constexpr.cc