Re: [RFH] gcc constant expression warning...
Junio C Hamano <gitster@pobox.com> kirjoitti 28.10.2007:
Show 12 quoted lines
> With the recent gcc, we get:
>
> sha1_file.c: In check_packed_git_:
> sha1_file.c:527: warning: assuming signed overflow does not
> occur when assuming that (X + c) < X is always false
> sha1_file.c:527: warning: assuming signed overflow does not
> occur when assuming that (X + c) < X is always false
>
> when compiling with
>
> -O2 -Werror -Wall -Wold-style-definition \
> -ansi -pedantic -std=c99 -Wdeclaration-after-statement
-ansi and -std=c99 in the same command line is a bit weird, BTW :)
Show 7 quoted lines
> The offending lines are:
>
> if (idx_size != min_size) {
> /* make sure we can deal with large pack offsets */
> off_t x = 0x7fffffffUL, y = 0xffffffffUL;
> if (x > (x + 1) || y > (y + 1)) {
> munmap(idx_map, idx_size);The second if line invokes undefined behavior if off_t cannot represent 0x7fffffffUL + 1. GCC apparently takes that as a license to ignore overflow and rewrite that if as "if (0) { ...".
A fast fix is to compile with -fwrapv or with -fno-strict-overflow:
-fstrict-overflow
Allow the compiler to assume strict signed overflow rules, depending
on the language being compiled. For C (and C++) this means that
overflow when doing arithmetic with signed numbers is undefined,
which means that the compiler may assume that it will not happen.
This permits various optimizations. For example, the compiler will
assume that an expression like i + 10 > i will always be true for
signed i. This assumption is only valid if signed overflow is
undefined, as the expression is false if i + 10 overflows when using
twos complement arithmetic. When this option is in effect any
attempt to determine whether an operation on signed numbers will
overflow must be written carefully to not actually involve overflow. See also the -fwrapv option. Using -fwrapv means that signed
overflow is fully defined: it wraps. When -fwrapv is used, there is
no difference between -fstrict-overflow and -fno-strict-overflow.
With -fwrapv certain types of overflow are permitted. For example,
if the compiler gets an overflow when doing arithmetic on constants,
the overflowed value can still be used with -fwrapv, but not
otherwise. The -fstrict-overflow option is enabled at levels -O2, -O3, -Os.
-fwrapv
This option instructs the compiler to assume that signed arithmetic
overflow of addition, subtraction and multiplication wraps around
using twos-complement representation. This flag enables some
optimizations and disables others. This option is enabled by default
for the Java front-end, as required by the Java language
specification. (From the GCC 4.2.2 manual.)
A correct fix would be to check for the size of off_t in some other (and defined) manner, but I don't know off_t well enough to suggest one. Considering that the size of off_t won't change at runtime, the test ought to be compile (or configure) time. Reading POSIX, there seem to be some rather cumbersome sysconf stuff one could test for, and of course CHAR_BIT * sizeof(off_t) also tells one something. GNU autoconf might also have a solution at hand.
--
Antti-Juhani Kaijanaho, Jyväskylä, Finland