OSDN Git Service

runtime: Return random number of hash of NaN.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 22 Sep 2012 06:06:53 +0000 (06:06 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 22 Sep 2012 06:06:53 +0000 (06:06 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@191633 138bc75d-0d04-0410-961f-82ee72b054a4

libgo/runtime/go-type-complex.c
libgo/runtime/go-type-float.c

index f923c86..106024f 100644 (file)
@@ -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;
index cc6e247..e1c03e4 100644 (file)
@@ -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