From: Jonathan Wakely Date: Fri, 16 May 2025 12:33:23 +0000 (+0100) Subject: libstdc++: Ensure std::hash<__int128> is defined [PR96710] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57b9afc9dad76f529969c548214b65dfe43652a7;p=thirdparty%2Fgcc.git libstdc++: Ensure std::hash<__int128> is defined [PR96710] 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): Likewise. * testsuite/20_util/hash/int128.cc: New test. Reviewed-by: Tomasz KamiƄski --- 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 +#include + +int main() +{ +#ifdef __SIZEOF_INT128__ + std::hash<__int128> h; + __int128 i = (__int128)0x123456789; + VERIFY( h(i) == i ); + VERIFY( h(-i) == (std::size_t)-i ); + VERIFY( h(~i) == (std::size_t)~i ); + std::hash hu; + unsigned __int128 u = i; + VERIFY( hu(u) == u ); + VERIFY( hu(~u) == (std::size_t)~u ); +#endif +}