On Mon, Jul 14, 2025 at 1:34 PM Jonathan Wakely <jwak...@redhat.com> wrote:
>
> This is a follow-up to r16-2190-g4faa42ac0dee2c which ensures that
> std::hash is always enabled for signed and unsigned __int128. The
> standard requires std::hash to be enabled for all arithmetic types.
>
> libstdc++-v3/ChangeLog:
>
>         PR libstdc++/96710
>         * include/bits/functional_hash.h (hash<__int128>): Define for
>         strict modes.
>         (hash<unsigned __int128>): Likewise.
>         * testsuite/20_util/hash/int128.cc: New test.
> ---
>
> Tested x86_64-linux.
>
> Truncating the result to size_t is unfortunate, but maybe too late to
> change. I've opened PR 121071 for that, as it also affect long long on
> 32-bit targets.
>
>  libstdc++-v3/include/bits/functional_hash.h   |  9 +++++++++
>  libstdc++-v3/testsuite/20_util/hash/int128.cc | 20 +++++++++++++++++++
>  2 files changed, 29 insertions(+)
>  create mode 100644 libstdc++-v3/testsuite/20_util/hash/int128.cc
>
> diff --git a/libstdc++-v3/include/bits/functional_hash.h 
> b/libstdc++-v3/include/bits/functional_hash.h
> index e84c9ee04be2..8456089f768d 100644
> --- a/libstdc++-v3/include/bits/functional_hash.h
> +++ b/libstdc++-v3/include/bits/functional_hash.h
> @@ -199,6 +199,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>    _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3 unsigned)
>  #endif
>
> +#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
> +  // In strict modes __GLIBCXX_TYPE_INT_N_0 is not defined for __int128,
> +  // but we want to always treat signed/unsigned __int128 as integral types.
> +  __extension__
> +  _Cxx_hashtable_define_trivial_hash(__int128)
> +  __extension__
> +  _Cxx_hashtable_define_trivial_hash(__int128 unsigned)
> +#endif
> +
>  #undef _Cxx_hashtable_define_trivial_hash
>
>    struct _Hash_impl
> diff --git a/libstdc++-v3/testsuite/20_util/hash/int128.cc 
> b/libstdc++-v3/testsuite/20_util/hash/int128.cc
> new file mode 100644
> index 000000000000..7c3a1baa0ec6
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/20_util/hash/int128.cc
> @@ -0,0 +1,20 @@
> +// { dg-do run { target c++11 } }
> +// { dg-add-options strict_std }
> +
> +#include <functional>
> +#include <testsuite_hooks.h>
> +
> +int main()
> +{
> +#ifdef __SIZEOF_INT128__
> +  std::hash<__int128> h;
> +  __int128 i = (__int128)0x123456789;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121150

> +  VERIFY( h(i) == i );
> +  VERIFY( h(-i) == (std::size_t)-i );
> +  VERIFY( h(~i) == (std::size_t)~i );
> +  std::hash<unsigned __int128> hu;
> +  unsigned __int128 u = i;
> +  VERIFY( hu(u) == u );
> +  VERIFY( hu(~u) == (std::size_t)~u );
> +#endif
> +}
> --
> 2.50.1
>


-- 
H.J.

Reply via email to