[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