[PATCH] libstdc++: Include bool conversion in noexcept specification of indirect::operator==.

Tomasz Kamiński tkaminsk@redhat.com
Wed Apr 22 14:16:41 GMT 2026


This expands the resolution of LWG4325 to heterogenous comparision
with T per standard draft (see corresponding commit [1]).

[1] https://github.com/cplusplus/draft/pull/8935/changes/833d635d648cdbd06c9935acccf925ee0aea3c79

libstdc++-v3/ChangeLog:

	* include/bits/indirect.h (indirect::operator==): Adjust
	noexcept specification.
	* testsuite/std/memory/indirect/relops.cc: New test for noexcept
	specification.
---
Tested only *indirect* test at this moment. Will not be able to merge
it until tomorrow.

Testing on x86_64-linux. OK for trunk if all test passes?

 libstdc++-v3/include/bits/indirect.h          |  4 +-
 .../testsuite/std/memory/indirect/relops.cc   | 43 +++++++++++++++++++
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/indirect.h b/libstdc++-v3/include/bits/indirect.h
index 6490a77a507..5be6713eaf3 100644
--- a/libstdc++-v3/include/bits/indirect.h
+++ b/libstdc++-v3/include/bits/indirect.h
@@ -336,7 +336,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	requires requires (const _Tp& __t, const _Up& __u) { __t == __u; }
 	friend constexpr bool
 	operator==(const indirect& __lhs, const indirect<_Up, _Alloc2>& __rhs)
-	noexcept(noexcept(*__lhs == *__rhs))
+	noexcept(noexcept(bool(*__lhs == *__rhs)))
 	{
 	  if (!__lhs._M_objp || !__rhs._M_objp)
 	    return bool(__lhs._M_objp) == bool(__rhs._M_objp);
@@ -349,7 +349,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  && requires (const _Tp& __t, const _Up& __u) { __t == __u; }
 	friend constexpr bool
 	operator==(const indirect<_Vp, _Alloc>& __lhs, const _Up& __rhs)
-	noexcept(noexcept(*__lhs == __rhs))
+	noexcept(noexcept(bool(*__lhs == __rhs)))
 	{
 	  if (!__lhs._M_objp)
 	    return false;
diff --git a/libstdc++-v3/testsuite/std/memory/indirect/relops.cc b/libstdc++-v3/testsuite/std/memory/indirect/relops.cc
index 77d599c8086..25ebf524e2b 100644
--- a/libstdc++-v3/testsuite/std/memory/indirect/relops.cc
+++ b/libstdc++-v3/testsuite/std/memory/indirect/relops.cc
@@ -68,11 +68,54 @@ test_hash()
   (void)std::hash<std::indirect<Obj>>{}(i);
 }
 
+template<bool Noexcept>
+struct BoolConv
+{
+  bool b;
+
+  constexpr BoolConv(bool p) noexcept
+  : b(p)
+  { }
+
+  constexpr operator bool() const noexcept(Noexcept)
+  { return b; }
+};
+
+template<bool NoexceptEq, typename Ret = bool>
+struct Comp
+{
+  friend constexpr Ret
+  operator==(const Comp&, const Comp&) noexcept(NoexceptEq)
+  { return true; }
+};
+
+template<bool NoexceptEq, typename T>
+void test_noexcept(T t)
+{
+  std::indirect<T> i(t);
+  static_assert(noexcept(i == t) == NoexceptEq);
+  static_assert(noexcept(i != t) == NoexceptEq);
+  static_assert(noexcept(i == i) == NoexceptEq);
+  static_assert(noexcept(i != i) == NoexceptEq);
+}
+
+void test_noexcept()
+{
+  test_noexcept<true>(Comp<true>());
+  test_noexcept<false>(Comp<false>());
+
+  test_noexcept<true>(Comp<true, BoolConv<true>>());
+  test_noexcept<false>(Comp<true, BoolConv<false>>());
+  test_noexcept<false>(Comp<false, BoolConv<true>>());
+  test_noexcept<false>(Comp<false, BoolConv<false>>());
+}
+
 int main()
 {
   test_relops();
   test_comp_with_t();
   test_hash();
+  test_noexcept();
 
   static_assert([] {
     test_relops();
-- 
2.53.0



More information about the Libstdc++ mailing list