diff options
author | Patrick Palka <ppalka@redhat.com> | 2025-05-12 09:15:34 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2025-05-12 09:15:34 -0400 |
commit | 91bc8169edd9038d78f38bd813287d72e6345c26 (patch) | |
tree | 67e180564796ca95253195ddca4225c16f42db5f | |
parent | af062510f4179aa7b13e632f77593deee8fe29f2 (diff) | |
download | gcc-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/expected | 4 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/expected/119714.cc | 9 |
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>); |