[PATCH v2] libstdc++: Include bool conversion in noexcept specification of indirect::operator==.
Jonathan Wakely
jwakely@redhat.com
Thu Apr 23 08:53:31 GMT 2026
On Thu, 23 Apr 2026 at 09:17, Tomasz Kamiński <tkaminsk@redhat.com> wrote:
>
> 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.
>
> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
> ---
> v2 adds test for noexcept of relation operators (libsdc++ extension).
>
> Tested on x86_64-linux. OK for trunk?
OK for trunk
>
> 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 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..fb957a7ad3d 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();
> --
> 2.53.0
>
More information about the Libstdc++
mailing list