https://gcc.gnu.org/g:57b9afc9dad76f529969c548214b65dfe43652a7
commit r16-2253-g57b9afc9dad76f529969c548214b65dfe43652a7 Author: Jonathan Wakely <jwak...@redhat.com> Date: Fri May 16 13:33:23 2025 +0100 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<unsigned __int128>): Likewise. * testsuite/20_util/hash/int128.cc: New test. Reviewed-by: Tomasz KamiĆski <tkami...@redhat.com> Diff: --- libstdc++-v3/include/bits/functional_hash.h | 9 +++++++++ libstdc++-v3/testsuite/20_util/hash/int128.cc | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+) 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; + 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 +}