Created attachment 24429 [details] test case When -Wstrict-overflow is used, gcc reports a warning "assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2" on a location where 1) gcc ought to be able to infer that there is no wraparound. 2) gcc emits this warning only when a certain other function is present in the same compilation unit. How to reproduce: $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/data/arch/x86-linux/gnu-inst-gcc/4.6.0/bin/../libexec/gcc/i686-pc-linux-gnu/4.6.0/lto-wrapper Target: i686-pc-linux-gnu Configured with: ../gcc-4.6.0/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=i686-pc-linux-gnu --prefix=/arch/x86-linux/gnu-inst-gcc/4.6.0 --enable-shared --enable-version-specific-runtime-libs --enable-nls --enable-threads=posix --enable-__cxa_atexit --with-as=/arch/x86-linux/gnu/bin/as32 --with-gmp=/arch/x86-linux/gnu-inst-gcc/4.6.0 --with-mpfr=/arch/x86-linux/gnu-inst-gcc/4.6.0 --with-mpc=/arch/x86-linux/gnu-inst-gcc/4.6.0 --with-libelf=/arch/x86-linux/gnu-inst-gcc/4.6.0 --with-ecj-jar=/gfs/petix/Volumes/ExtData/source/gnu/gcc/sourceware.org-ecj/ecj-latest.jar Thread model: posix gcc version 4.6.0 (GCC) $ gcc -Wstrict-overflow -O2 -S foo.c foo.c: In function 'yylex': foo.c:2026:18: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] foo.c: In function 'yyparse': foo.c:1442:6: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] foo.c:1442:6: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] foo.c:2026:18: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] foo.c:1407:1: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] foo.c:2026:18: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] foo.c:2026:18: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] foo.c:1442:6: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] foo.c:2026:18: warning: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Wstrict-overflow] 1) Line 2026 contains the expression (p < buff + sizeof buff - 1) but buff is an array of constant size, sizeof buff is 20. gcc ought to be able to infer that (buff + 19) does not wrap around. 2) If the function yyparse is removed from foo.c, the warning disappears. So apparently the warning is generated when inlining yylex into yyparse. It makes no sense to have no warning in yylex by itself but have a warning when it gets inlined.
(In reply to comment #0) > 2) If the function yyparse is removed from foo.c, the warning disappears. > So apparently the warning is generated when inlining yylex into yyparse. > It makes no sense to have no warning in yylex by itself but have a warning > when it gets inlined. Unfortunately, this perfectly makes sense and, in fact, it happens often. Inlining exposes more optimization opportunities and hence more changes of making use of undefined behaviour. See: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_21.html#more
1) Line 2026 contains the expression (p < buff + sizeof buff - 1) GCC only looks at local tuple stmts when emitting the warning, so I suppose it sees sth like p = &buff[...]; p = p + 3; (p < buff + sizeof buff - 1) and then optimizes the last two stmts as p + 3 < buff + sizeof buff - 1 moving the + 3 from the LHS and combining it with the constant offset on the RHS. That is only valid if p + 3 does not get outside of buff which GCC doesn't see (it would also be invalid, but that is what the option tries to catch - so, catch22).
(In reply to comment #2) > [GCC] optimizes [...] > moving the + 3 from the LHS and combining it with the constant offset > on the RHS. That is only valid if p + 3 does not get outside of buff > which GCC doesn't see Rather than performing an invalid optimization (that is, produce wrong-code) with a warning, I would prefer if GCC would simply only do valid optimizations. Code ought to be written to be maintainable. If code has to be changed, so as to avoid invalid optimizations from a compiler, then 1. it becomes a lot of work to change the code so that all compilers on all supported platforms are pleased, 2. the maintainability of the code suffers. I did not enable particular, dangerous optimization options. Just "-O2", which is the default setting in every package that uses autoconf.
(In reply to bruno from comment #3) > (In reply to comment #2) > > [GCC] optimizes [...] > > moving the + 3 from the LHS and combining it with the constant offset > > on the RHS. That is only valid if p + 3 does not get outside of buff > > which GCC doesn't see > > Rather than performing an invalid optimization (that is, produce wrong-code) > with a warning, I would prefer if GCC would simply only do valid > optimizations. In general, it is not possible to say that a program is valid or not while compiling it. (It might be possible in this case, nonetheless, I haven't looked at the details) This case in particular seems too noisy (and the warning message itself does not help to figure out what is wrong). Perhaps we should not enabled by default this one in particular