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