Bug 49283 - pointless warning with -Wstrict-overflow
pointless warning with -Wstrict-overflow
Status: NEW
Product: gcc
Classification: Unclassified
Component: middle-end
4.6.0
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
: diagnostic
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-06-04 13:19 UTC by bruno
Modified: 2014-10-03 14:33 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-10-03 00:00:00


Attachments
test case (72.26 KB, text/x-csrc)
2011-06-04 13:19 UTC, bruno
Details

Note You need to log in before you can comment on or make changes to this bug.
Description bruno 2011-06-04 13:19:32 UTC
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.
Comment 1 Manuel López-Ibáñez 2011-06-05 09:00:41 UTC
(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
Comment 2 Richard Biener 2011-06-06 10:38:33 UTC
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).
Comment 3 bruno 2011-06-06 20:33:07 UTC
(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.
Comment 4 Manuel López-Ibáñez 2014-10-03 14:33:58 UTC
(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