[gcc r17-37] libstdc++: Include bool conversion in noexcept specification of indirect::operator==.
Tomasz Kaminski
tkaminsk@gcc.gnu.org
Thu Apr 23 11:06:23 GMT 2026
https://gcc.gnu.org/g:2985bacae46a61f70ac5bfbf3b6d3a943e538860
commit r17-37-g2985bacae46a61f70ac5bfbf3b6d3a943e538860
Author: Tomasz Kamiński <tkaminsk@redhat.com>
Date: Wed Apr 22 16:10:26 2026 +0200
libstdc++: Include bool conversion in noexcept specification of indirect::operator==.
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.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
Diff:
---
libstdc++-v3/include/bits/indirect.h | 4 +-
.../testsuite/std/memory/indirect/relops.cc | 72 ++++++++++++++++++++++
2 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/libstdc++-v3/include/bits/indirect.h b/libstdc++-v3/include/bits/indirect.h
index 6490a77a5079..5be6713eaf3f 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 77d599c80861..fb957a7ad3d3 100644
--- a/libstdc++-v3/testsuite/std/memory/indirect/relops.cc
+++ b/libstdc++-v3/testsuite/std/memory/indirect/relops.cc
@@ -68,11 +68,83 @@ 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 Noexcept, typename EqRet = bool>
+struct Comp
+{
+ friend constexpr EqRet
+ operator==(const Comp&, const Comp&) noexcept(Noexcept)
+ { return true; }
+
+ friend constexpr std::strong_ordering
+ operator<=>(const Comp&, const Comp&) noexcept(Noexcept)
+ { return std::strong_ordering::equal; }
+};
+
+template<bool Noexcept, typename T>
+void test_noexcept_eq(T t)
+{
+ std::indirect<T> i(t);
+ static_assert(noexcept(i == t) == Noexcept);
+ static_assert(noexcept(i != t) == Noexcept);
+ static_assert(noexcept(i == i) == Noexcept);
+ static_assert(noexcept(i != i) == Noexcept);
+}
+
+template<bool Noexcept, typename T>
+void test_noexcept_rel(T t)
+{
+ std::indirect<T> i(t);
+ static_assert(noexcept(i < t) == Noexcept);
+ static_assert(noexcept(i > t) == Noexcept);
+ static_assert(noexcept(i <= t) == Noexcept);
+ static_assert(noexcept(i >= t) == Noexcept);
+ static_assert(noexcept(i <=> t) == Noexcept);
+
+ static_assert(noexcept(t < i) == Noexcept);
+ static_assert(noexcept(t > i) == Noexcept);
+ static_assert(noexcept(t <= i) == Noexcept);
+ static_assert(noexcept(t >= i) == Noexcept);
+ static_assert(noexcept(t <=> i) == Noexcept);
+
+ static_assert(noexcept(i < i) == Noexcept);
+ static_assert(noexcept(i > i) == Noexcept);
+ static_assert(noexcept(i <= i) == Noexcept);
+ static_assert(noexcept(i >= i) == Noexcept);
+ static_assert(noexcept(i <=> i) == Noexcept);
+}
+
+void test_noexcept()
+{
+ test_noexcept_eq<true>(Comp<true>());
+ test_noexcept_eq<false>(Comp<false>());
+ test_noexcept_rel<true>(Comp<true>());
+ test_noexcept_rel<false>(Comp<false>());
+
+ test_noexcept_eq<true>(Comp<true, BoolConv<true>>());
+ test_noexcept_eq<false>(Comp<true, BoolConv<false>>());
+ test_noexcept_eq<false>(Comp<false, BoolConv<true>>());
+ test_noexcept_eq<false>(Comp<false, BoolConv<false>>());
+}
+
int main()
{
test_relops();
test_comp_with_t();
test_hash();
+ test_noexcept();
static_assert([] {
test_relops();
More information about the Libstdc++-cvs
mailing list