[PATCH] libstdc++: Fix constraint recursion in std:indirect's operator== [PR124890]
Patrick Palka
ppalka@redhat.com
Fri Apr 17 17:02:52 GMT 2026
On Fri, 17 Apr 2026, Jonathan Wakely wrote:
> 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)
Oops, forgot to pass the _Alloc parameter here. Here's what I ended up
pushing:
-- >8 --
Subject: [PATCH] libstdc++: Fix constraint recursion in std::indirect's
operator== [PR124890]
Like in r16-559 for std::expected, std::indirect's operator== is also
prone to constraint recursion due to CWG 2369, for the Mandates that we
implement as an associated constraint. This patch works around the
recursion in a similar manner as done for std::expected (and
std::basic_const_iterator).
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<_Vp> where _Vp matches _Tp.
* testsuite/std/memory/indirect/124890.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
---
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..6490a77a5079 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<typename _Up, same_as<_Tp> _Vp>
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<_Vp, _Alloc>& __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