diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-09-22 06:06:31 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-09-22 06:06:31 +0000 |
commit | 603be56a77ce92ed52dd889f2bd7dc271bdf1b25 (patch) | |
tree | 2ce5d179f6bcc6d9d87f045f082c26dcf3870c0b /libgo/runtime | |
parent | c849bb594f2d84ac5300d24c92384db338820de7 (diff) | |
download | gcc-603be56a77ce92ed52dd889f2bd7dc271bdf1b25.tar.gz |
runtime: Return random number of hash of NaN.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191632 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/runtime')
-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 f923c867d99..106024f5c88 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 cc6e247e531..e1c03e42843 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 |