aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-09-22 06:06:31 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-09-22 06:06:31 +0000
commit2afc1e0b30efd4b6460a42e692314a82832676bd (patch)
tree2ce5d179f6bcc6d9d87f045f082c26dcf3870c0b /libgo
parenta7a904566298c4a7a5712ddc0f631f843224ff0b (diff)
downloadgcc-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.c14
-rw-r--r--libgo/runtime/go-type-float.c14
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