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