Subject: Re: bug#6524: du now uses less than half as much memory, sometimes

From: Paul Eggert <[email-masked]>
Date: Tue, 06 Jul 2010 16:22:50 -0700

On 07/06/10 15:18, Jim Meyering wrote:

> A minor nit for next time:
>   du: Hash with a mechanism that's simpler and takes less memory.
> please do not capitalize and omit the period on the one-line summary

Sorry, I'll try to remember better next time.

> It fails to compile on x86_64 with -Werror: ...
>   di-set.c:86: error: right shift count >= width of type

That's an incorrect warning, since the code is unreachable on
that platform and the compiler should know that it's unreachable.
This bug has been present in GCC for ages, with no signs of it
ever getting fixed.  In this particular case it's fairly easy
to work around with no runtime penalty assuming reasonable
optimization (except perhaps on weird hosts where
sizeof (ino_t) > 2 * sizeof (size_t)) so I installed
this further patch:

>From db4df7dda6e209e3e38fe69298624ffe92d392c7 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 6 Jul 2010 16:16:20 -0700
Subject: [PATCH] du: avoid spurious warnings with 64-bit gcc -W

Problem reported by Jim Meyering in:
http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6524#74
* gl/lib/di-set.c (di_ent_hash): Rework so that the compiler does
not incorrectly warn about shifting by 64-bits in unreachable code.
* gl/lib/ino-map.c (ino_hash): Likewise.
---
 gl/lib/di-set.c  |    2 +-
 gl/lib/ino-map.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gl/lib/di-set.c b/gl/lib/di-set.c
index e0e2b24..ba44bcf 100644
--- a/gl/lib/di-set.c
+++ b/gl/lib/di-set.c
@@ -83,7 +83,7 @@ di_ent_hash (void const *x, size_t table_size)
   size_t h = dev;
   int i;
   for (i = 1; i < sizeof dev / sizeof h + (sizeof dev % sizeof h != 0); i++)
-    h ^= dev >>= CHAR_BIT * sizeof h;
+    h ^= dev >> CHAR_BIT * sizeof h * i;
 
   return h % table_size;
 }
diff --git a/gl/lib/ino-map.c b/gl/lib/ino-map.c
index c868983..cc9a131 100644
--- a/gl/lib/ino-map.c
+++ b/gl/lib/ino-map.c
@@ -61,7 +61,7 @@ ino_hash (void const *x, size_t table_size)
   size_t h = ino;
   int i;
   for (i = 1; i < sizeof ino / sizeof h + (sizeof ino % sizeof h != 0); i++)
-    h ^= ino >>= CHAR_BIT * sizeof h;
+    h ^= ino >> CHAR_BIT * sizeof h * i;
 
   return h % table_size;
 }
-- 
1.7.0.4