diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-09-22 06:06:31 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-09-22 06:06:31 +0000 |
commit | 2afc1e0b30efd4b6460a42e692314a82832676bd (patch) | |
tree | 2ce5d179f6bcc6d9d87f045f082c26dcf3870c0b /libgo | |
parent | a7a904566298c4a7a5712ddc0f631f843224ff0b (diff) | |
download | gcc-2afc1e0b30efd4b6460a42e692314a82832676bd.zip gcc-2afc1e0b30efd4b6460a42e692314a82832676bd.tar.gz gcc-2afc1e0b30efd4b6460a42e692314a82832676bd.tar.bz2 |
runtime: Return random number of hash of NaN.
From-SVN: r191632
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/runtime/go-type-complex.c | 14 | ||||
-rw-r--r-- | 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 f923c867..106024f 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 cc6e247..e1c03e4 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 |