Subject: bug#11927: shred.c i686-specific warning from gcc-4.7 on fedora 17

From: Jim Meyering <[email-masked]>
Date: Thu, 12 Jul 2012 23:27:15 +0200

[mostly for the record, and so I don't forget.
 I'm not ready to push this just yet. ]

Building shred with fedora 17 and its stock gcc 4.7 on i686,
I see this warning/error:

    CC     shred.o
  shred.c: In function 'dopass':
  shred.c:501:14: error: assuming signed overflow does not occur when simplifying conditional to constant [-Werror=strict-overflow]
  shred.c:504:18: error: assuming signed overflow does not occur when simplifying conditional to constant [-Werror=strict-overflow]
  cc1: all warnings being treated as errors
  make[3]: *** [shred.o] Error 1
  make[3]: Leaving directory `/f12/home/meyering/w/co/cu/src'
  make[2]: *** [all] Error 2
  make[2]: Leaving directory `/f12/home/meyering/w/co/cu/src'
  make[1]: *** [all-recursive] Error 1
  make[1]: Leaving directory `/f12/home/meyering/w/co/cu'
  make: *** [all] Error 2

I didn't really understand the cause but ended up
writing the following patch to avoid the problem
while making the code slightly more readable:

diff --git a/src/shred.c b/src/shred.c
index 7a28260..322bcf1 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -485,10 +485,11 @@ dopass (int fd, char const *qname, off_t *sizep, int type,

       offset += soff;

+      bool done = offset == size;
+
       /* Time to print progress? */
-      if (n
-          && ((offset == size && *previous_human_offset)
-              || thresh <= (now = time (NULL))))
+      if (n && ((done && *previous_human_offset)
+                || thresh <= (now = time (NULL))))
         {
           char offset_buf[LONGEST_HUMAN_READABLE + 1];
           char size_buf[LONGEST_HUMAN_READABLE + 1];
@@ -498,8 +499,7 @@ dopass (int fd, char const *qname, off_t *sizep, int type,
             = human_readable (offset, offset_buf,
                               human_floor | human_progress_opts, 1, 1);

-          if (offset == size
-              || !STREQ (previous_human_offset, human_offset))
+          if (done || !STREQ (previous_human_offset, human_offset))
             {
               if (size < 0)
                 error (0, 0, _("%s: pass %lu/%lu (%s)...%s"),
@@ -516,7 +516,7 @@ dopass (int fd, char const *qname, off_t *sizep, int type,
                     = human_readable (size, size_buf,
                                       human_ceiling | human_progress_opts,
                                       1, 1);
-                  if (offset == size)
+                  if (done)
                     human_offset = human_size;
                   error (0, 0, _("%s: pass %lu/%lu (%s)...%s/%s %d%%"),
                          qname, k, n, pass_string, human_offset, human_size,