aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2025-05-12 09:15:34 -0400
committerPatrick Palka <ppalka@redhat.com>2025-05-12 09:15:34 -0400
commit91bc8169edd9038d78f38bd813287d72e6345c26 (patch)
tree67e180564796ca95253195ddca4225c16f42db5f
parentaf062510f4179aa7b13e632f77593deee8fe29f2 (diff)
downloadgcc-91bc8169edd9038d78f38bd813287d72e6345c26.zip
gcc-91bc8169edd9038d78f38bd813287d72e6345c26.tar.gz
gcc-91bc8169edd9038d78f38bd813287d72e6345c26.tar.bz2
libstdc++: Fix constraint recursion in std::expected's operator== [PR119714]
This std::expected friend operator== is prone to constraint recursion after CWG 2369 for the same reason as basic_const_iterator's comparison operators were before the r15-7757-g4342c50ca84ae5 workaround. This patch works around the constraint recursion here in a similar manner, by making the function parameter of type std::expected dependent in a trivial way. PR libstdc++/119714 PR libstdc++/112490 libstdc++-v3/ChangeLog: * include/std/expected (expected::operator==): Replace non-dependent std::expected function parameter with a dependent one of type expected<_Vp, _Er> where _Vp matches _Tp. * testsuite/20_util/expected/119714.cc: New test. Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
-rw-r--r--libstdc++-v3/include/std/expected4
-rw-r--r--libstdc++-v3/testsuite/20_util/expected/119714.cc9
2 files changed, 11 insertions, 2 deletions
diff --git a/libstdc++-v3/include/std/expected b/libstdc++-v3/include/std/expected
index 5dc1dfb..60f1565 100644
--- a/libstdc++-v3/include/std/expected
+++ b/libstdc++-v3/include/std/expected
@@ -1169,13 +1169,13 @@ namespace __expected
return !__y.has_value() && bool(__x.error() == __y.error());
}
- template<typename _Up>
+ template<typename _Up, same_as<_Tp> _Vp>
requires (!__expected::__is_expected<_Up>)
&& requires (const _Tp& __t, const _Up& __u) {
{ __t == __u } -> convertible_to<bool>;
}
friend constexpr bool
- operator==(const expected& __x, const _Up& __v)
+ operator==(const expected<_Vp, _Er>& __x, const _Up& __v)
noexcept(noexcept(bool(*__x == __v)))
{ return __x.has_value() && bool(*__x == __v); }
diff --git a/libstdc++-v3/testsuite/20_util/expected/119714.cc b/libstdc++-v3/testsuite/20_util/expected/119714.cc
new file mode 100644
index 0000000..a8dc6e8
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/expected/119714.cc
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++23 } }
+
+// PR libstdc++/119714 - constraint recursion with std::expected::operator==
+
+#include <expected>
+#include <vector>
+
+using I = std::vector<std::expected<int,int>>::iterator;
+static_assert(std::totally_ordered<I>);