Maintainers of GNU packages that use gnulib are now starting to see
bug reports coming in from installers using GCC 4.0.0 on 64-bit
platforms.  GCC is issuing an incorrect warning about valid code, but
installers don't necessarily know the code is valid, so they are
worried about it.

This is a regression, since GCC 3.x did not issue these warnings.  (I
just checked this, with GCC 3.2.3.)  I presume that the new warnings
occur because GCC 4.x is "smarter" about detecting the situation.

Example logs containing the bogus warnings can be found here (look for
"quotearg"):

http://lists.gnu.org/archive/html/bug-gnulib/2005-06/msg00076.html
http://josefsson.org/autobuild-logs/base64-1.1-192.233.54.149-output.html
http://hood.oook.cz/tb/logs/5-amd64-FreeBSD/gettext-0.14.4_1.log

Here is a small program that illustrates the problem.  Compile this
for a 64-bit platform (where size_t is 64 bits and int is 32 bits).
I used "gcc -c -m64 t.c" on Solaris 8 sparc.

   /* Return 1 if an array of N objects, each of size S, cannot exist due
      to size arithmetic overflow.  S must be positive and N must be
      nonnegative.  This is a macro, not an inline function, so that it
      works correctly even when SIZE_MAX < N.

      By gnulib convention, SIZE_MAX represents overflow in size
      calculations, so the conservative dividend to use here is
      SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
      However, malloc (SIZE_MAX) fails on all known hosts where
      sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
      exactly-SIZE_MAX allocations on such hosts; this avoids a test and
      branch when S is known to be 1.  */
   # define xalloc_oversized(n, s) \
       ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))

   #include <stddef.h>

   int
   too_large (unsigned int n)
   {
     return xalloc_oversized (n, sizeof (double));
   }

GCC 4.0.0 issues a diagnostic like this:

$ gcc --version | sed 1q
gcc (GCC) 4.0.0
$ gcc -c -m64 t.c
t.c: In function 'too_large':
t.c:21: warning: comparison is always false due to limited range of data type

This warning is bogus, because the whole point of the xalloc_oversized
macro is to avoid a run-time comparison when possible.  In effect, GCC
4.0.0 is warning the user that it is smart enough to generate better
code.  I see no easy way to modify the code to work around the warning
(other than by making the code less efficient).

Looking at the GCC 4.x source code, it appears that other, similar
warnings are all enabled only if -Wextra is specified.  These include:

comparison of unsigned expression >= 0 is always true
comparison of unsigned expression < 0 is always false

These warnings are similar because they also are comparisons that
return false (or true) due to the limited range of the data type.

Logically, the troublesome warnings fall into the same category as
these unsigned-expressions warnings, so they should be enabled only if
the unsigned-expression warnings are enabled: i.e., only when -Wextra
is specified and we are not in a system header.

Here is a proposed patch, against GCC sources I checked out today.

2005-06-24  Paul Eggert  <[EMAIL PROTECTED]>

        * c-common.c (shorten_compare): Unless -Wextra is used,
        do not warn against comparisons always being false due to
        limited range of data type.  Such comparisons can occur
        in real-world portable code dealing with system types
        like size_t.

--- c-common.c.~1.636.~ 2005-06-24 14:37:22.000000000 -0700
+++ c-common.c  2005-06-24 14:37:38.380239000 -0700
@@ -2117,7 +2117,8 @@ shorten_compare (tree *op0_ptr, tree *op
          type = c_common_unsigned_type (type);
        }
 
-      if (TREE_CODE (primop0) != INTEGER_CST)
+      if (extra_warnings && !in_system_header
+         && TREE_CODE (primop0) != INTEGER_CST)
        {
          if (val == truthvalue_false_node)
            warning (0, "comparison is always false due to limited range of 
data type");

-- 
           Summary: bogus warning "comparison is always false due to limited
                    range"
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: eggert at gnu dot org
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: sparc-sun-solaris2.10
  GCC host triplet: sparc-sun-solaris2.10
GCC target triplet: sparc-sun-solaris2.10


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22178

Reply via email to