[PATCH] libstdc++: Fix constraint recursion in std:indirect's operator== [PR124890]
Jonathan Wakely
jwakely@redhat.com
Fri Apr 17 15:43:08 GMT 2026
On Fri, 17 Apr 2026 at 16:40, Patrick Palka <ppalka@redhat.com> wrote:
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk?
OK, thanks.
>
> We can also just implement the Mandates as a static_assert as pointed
> out by Lénárd. Otherwise, I prefer this approach rather than the
> forwarding reference approach since it's cleaner and we use this approach
> in other parts of the library with no complaints so far.
>
> -- >8 --
>
> Like in r16-559 for std::expected, std::indirect's operator== is also
> prone to constraint recursion due to CWG 2369. This patch works around
> the recursion in a similar manner.
>
> PR libstdc++/124890
> PR libstdc++/119714
> PR libstdc++/112490
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/indirect.h (indirect::operator==): Replace
> non-dependent std::indirect function parameter with a
> dependent one of type indirect<_Tp2> where _Tp2 matches _Tp.
> * testsuite/std/memory/indirect/124890.cc: New test.
> ---
> libstdc++-v3/include/bits/indirect.h | 4 ++--
> libstdc++-v3/testsuite/std/memory/indirect/124890.cc | 9 +++++++++
> 2 files changed, 11 insertions(+), 2 deletions(-)
> create mode 100644 libstdc++-v3/testsuite/std/memory/indirect/124890.cc
>
> diff --git a/libstdc++-v3/include/bits/indirect.h b/libstdc++-v3/include/bits/indirect.h
> index 2df46cc39a21..e1f7d1968b56 100644
> --- a/libstdc++-v3/include/bits/indirect.h
> +++ b/libstdc++-v3/include/bits/indirect.h
> @@ -344,11 +344,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> return __lhs.__get() == __rhs.__get();
> }
>
> - template<typename _Up>
> + template<same_as<_Tp> _Tp2, typename _Up>
> requires (!__is_indirect<_Up>) // See PR c++/99599
> && requires (const _Tp& __t, const _Up& __u) { __t == __u; }
> friend constexpr bool
> - operator==(const indirect& __lhs, const _Up& __rhs)
> + operator==(const indirect<_Tp2>& __lhs, const _Up& __rhs)
> noexcept(noexcept(*__lhs == __rhs))
> {
> if (!__lhs._M_objp)
> diff --git a/libstdc++-v3/testsuite/std/memory/indirect/124890.cc b/libstdc++-v3/testsuite/std/memory/indirect/124890.cc
> new file mode 100644
> index 000000000000..ce44256f2244
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/std/memory/indirect/124890.cc
> @@ -0,0 +1,9 @@
> +// { dg-do compile { target c++26 } }
> +
> +// PR libstdc++/124890 - Circular constraint in std::indirect::operator==
> +
> +#include <memory>
> +#include <vector>
> +
> +using I = std::vector<std::indirect<int>>::iterator;
> +static_assert(std::totally_ordered<I>);
> --
> 2.54.0.rc1.54.g60f07c4f5c
>
More information about the Libstdc++
mailing list