From 2afc1e0b30efd4b6460a42e692314a82832676bd Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 22 Sep 2012 06:06:31 +0000 Subject: [PATCH] runtime: Return random number of hash of NaN. From-SVN: r191632 --- libgo/runtime/go-type-complex.c | 14 ++++++++++---- libgo/runtime/go-type-float.c | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/libgo/runtime/go-type-complex.c b/libgo/runtime/go-type-complex.c index f923c867d995..106024f5c88b 100644 --- a/libgo/runtime/go-type-complex.c +++ b/libgo/runtime/go-type-complex.c @@ -32,10 +32,14 @@ __go_type_hash_complex (const void *vkey, uintptr_t key_size) cf = ucf.cf; cfr = __builtin_crealf (cf); cfi = __builtin_cimagf (cf); - if (__builtin_isinff (cfr) || __builtin_isinff (cfi) - || __builtin_isnanf (cfr) || __builtin_isnanf (cfi)) + if (__builtin_isinff (cfr) || __builtin_isinff (cfi)) return 0; + /* NaN != NaN, so the hash code of a NaN is irrelevant. Make it + random so that not all NaNs wind up in the same place. */ + if (__builtin_isnanf (cfr) || __builtin_isnanf (cfi)) + return runtime_fastrand1 (); + /* Avoid negative zero. */ if (cfr == 0 && cfi == 0) return 0; @@ -62,10 +66,12 @@ __go_type_hash_complex (const void *vkey, uintptr_t key_size) cd = ucd.cd; cdr = __builtin_crealf (cd); cdi = __builtin_cimagf (cd); - if (__builtin_isinf (cdr) || __builtin_isinf (cdi) - || __builtin_isnan (cdr) || __builtin_isnan (cdi)) + if (__builtin_isinf (cdr) || __builtin_isinf (cdi)) return 0; + if (__builtin_isnan (cdr) || __builtin_isnan (cdi)) + return runtime_fastrand1 (); + /* Avoid negative zero. */ if (cdr == 0 && cdi == 0) return 0; diff --git a/libgo/runtime/go-type-float.c b/libgo/runtime/go-type-float.c index cc6e247e531c..e1c03e428439 100644 --- a/libgo/runtime/go-type-float.c +++ b/libgo/runtime/go-type-float.c @@ -29,8 +29,14 @@ __go_type_hash_float (const void *vkey, uintptr_t key_size) __builtin_memcpy (uf.a, vkey, 4); f = uf.f; - if (__builtin_isinff (f) || __builtin_isnanf (f) || f == 0) + if (__builtin_isinff (f) || f == 0) return 0; + + /* NaN != NaN, so the hash code of a NaN is irrelevant. Make it + random so that not all NaNs wind up in the same place. */ + if (__builtin_isnanf (f)) + return runtime_fastrand1 (); + return (uintptr_t) uf.si; } else if (key_size == 8) @@ -45,8 +51,12 @@ __go_type_hash_float (const void *vkey, uintptr_t key_size) __builtin_memcpy (ud.a, vkey, 8); d = ud.d; - if (__builtin_isinf (d) || __builtin_isnan (d) || d == 0) + if (__builtin_isinf (d) || d == 0) return 0; + + if (__builtin_isnan (d)) + return runtime_fastrand1 (); + return (uintptr_t) ud.di; } else