As PR c++/106212 shows, the Debug Mode checks cause a compilation error for equality comparisons involving std::array prvalues in constant expressions. Those Debug Mode checks are redundant when comparing two std::array objects, because we already know we have a valid range. We can also avoid the unnecessary step of using std::__niter_base to do __normal_iterator unwrapping, which isn't needed because our std::array iterators are just pointers. Using std::__equal_aux1 instead of std::equal avoids the redundant checks in std::equal and std::__equal_aux.
libstdc++-v3/ChangeLog: PR libstdc++/106212 * include/std/array (operator==): Use std::__equal_aux1 instead of std::equal. * testsuite/23_containers/array/comparison_operators/106212.cc: New test. --- This is similar to the _GLIBCXX_DEBUG failure for std::span, but from an older report for std::array. libstdc++-v3/include/std/array | 2 +- .../array/comparison_operators/106212.cc | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/23_containers/array/comparison_operators/106212.cc diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 172b3203ccd..1b1c5cc596e 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -303,7 +303,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR inline bool operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) - { return std::equal(__one.begin(), __one.end(), __two.begin()); } + { return std::__equal_aux1(__one.begin(), __one.end(), __two.begin()); } #if __cpp_lib_three_way_comparison // C++ >= 20 && lib_concepts template<typename _Tp, size_t _Nm> diff --git a/libstdc++-v3/testsuite/23_containers/array/comparison_operators/106212.cc b/libstdc++-v3/testsuite/23_containers/array/comparison_operators/106212.cc new file mode 100644 index 00000000000..f7b12bd04ef --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/array/comparison_operators/106212.cc @@ -0,0 +1,15 @@ +// { dg-options "-D_GLIBCXX_DEBUG" } +// { dg-do compile { target c++20 } } + +// Bug libstdc++/106212 - Code becomes non-constexpr with _GLIBCXX_DEBUG + +#include <array> + +struct A +{ + constexpr A(int i) : e{i} {} + constexpr bool operator==(const A& a) const = default; + std::array<int, 1> e; +}; + +static_assert(A{1} != A{2}, ""); -- 2.47.1