diff --git a/libstdc++-v3/include/bits/functional_hash.h b/libstdc++-v3/include/bits/functional_hash.h index e84c9ee04be..8456089f768 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 00000000000..7c3a1baa0ec --- /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 +}