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.