[PATCH 1/2] libstdc++: Ensure std::hash<__int128> is defined [PR96710]
H.J. Lu
hjl.tools@gmail.com
Thu Jul 17 23:06:06 GMT 2025
On Mon, Jul 14, 2025 at 1:34 PM Jonathan Wakely <jwakely@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.
More information about the Libstdc++
mailing list