Bug 60121 - gcc does not warn an obvious out-of-bound array access at -O0 and -O1
Summary: gcc does not warn an obvious out-of-bound array access at -O0 and -O1
Status: RESOLVED DUPLICATE of bug 60115
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-08 23:15 UTC by Zhendong Su
Modified: 2014-02-09 06:39 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2014-02-08 23:15:31 UTC
For the given testcase below, gcc doesn't warn the out-of-bound array access at -O0 and -O1, but does at -Os and above, while clang warns at all optimization levels. Since the out-of-bound access is obvious, I wonder whether gcc should also warn at -O0 and -O1. 

This affects the current gcc trunk and all earlier versions. 

$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-trunk/configure --prefix=/usr/local/gcc-trunk --enable-languages=c,c++ --disable-werror --enable-multilib
Thread model: posix
gcc version 4.9.0 20140208 (experimental) [trunk revision 207627] (GCC) 
$
$ gcc-trunk -Warray-bounds -O0 small.c
$ gcc-trunk -Warray-bounds -O1 small.c 
$     
$ gcc-trunk -Warray-bounds -Os small.c
small.c: In function ‘main’:
small.c:8:10: warning: array subscript is above array bounds [-Warray-bounds]
     if (b[613])
          ^
$
$ clang-trunk -Warray-bounds -O0 small.c
small.c:8:9: warning: array index 613 is past the end of the array (which contains 1 element) [-Warray-bounds]
    if (b[613])
        ^ ~~~
small.c:1:1: note: array 'b' declared here
int a, b[1];
^
1 warning generated.
$
Comment 1 Zhendong Su 2014-02-08 23:16:19 UTC
Here is the testcase: 


-------------------------


int a, b[1];

int
main ()
{
 lbl:
  for (; a; a--)
    if (b[613])
      goto lbl;
  
  return 0;
}
Comment 2 Andrew Pinski 2014-02-08 23:41:55 UTC
I think this is expected. out of bounds warnings come not from the front-end but the middle-end and are designed not to warn about in dead code.  This code is dead as a != 0 is always false.
Comment 3 Zhendong Su 2014-02-09 00:07:56 UTC
(In reply to Andrew Pinski from comment #2)
> I think this is expected. out of bounds warnings come not from the front-end
> but the middle-end and are designed not to warn about in dead code.  This
> code is dead as a != 0 is always false.

Andrew, it's actually the complete opposite with this testcase. 

At -O0 and -O1, gcc unlikely knows that the out-of-bound array access is dead, so the warning should be issued, but it's not. 

On the other hand, at -Os and above, gcc likely knows that the out-of-bound array access is dead, but it warns.
Comment 4 Andrew Pinski 2014-02-09 00:14:38 UTC
Actually the reason for the warning is due to LIM pulling the out of bounds access out of the loop, the same reason why bug 60115 fails.  It is just showing the bug a different way.

*** This bug has been marked as a duplicate of bug 60115 ***
Comment 5 Zhendong Su 2014-02-09 00:17:58 UTC
(In reply to Andrew Pinski from comment #4)
> Actually the reason for the warning is due to LIM pulling the out of bounds
> access out of the loop, the same reason why bug 60115 fails.  It is just
> showing the bug a different way.
> 
> *** This bug has been marked as a duplicate of bug 60115 ***

Andrew, you completely lost me ...  

Please note that this warning issue affects ALL earlier versions of GCC too, but 60115 only for the current 4.8 branch and the main trunk. 

Please check the report carefully. Thanks.
Comment 6 Chengnian Sun 2014-02-09 00:32:25 UTC
The test case can be further reduced to the following code, which is NOT dead or dependent on bug 60115. 

int b[1];
int f() {
  return b[9999];
}
Comment 7 Andrew Pinski 2014-02-09 00:47:32 UTC
(In reply to Chengnian Sun from comment #6)
> The test case can be further reduced to the following code, which is NOT
> dead or dependent on bug 60115. 
> 
> int b[1];
> int f() {
>   return b[9999];
> }

Because we don't warn in the front-end.  That was on purpose.  I can find the old bug reports of why we don't want to warn in the front-end.  The warning only happens in VPR which is only enabled for -O2 and above (-Os is -O2 plus optimize for size really).
Comment 8 Chengnian Sun 2014-02-09 01:27:38 UTC
(In reply to Andrew Pinski from comment #7)
> (In reply to Chengnian Sun from comment #6)
> > The test case can be further reduced to the following code, which is NOT
> > dead or dependent on bug 60115. 
> > 
> > int b[1];
> > int f() {
> >   return b[9999];
> > }
> 
> Because we don't warn in the front-end.  That was on purpose.  I can find
> the old bug reports of why we don't want to warn in the front-end.  The
> warning only happens in VPR which is only enabled for -O2 and above (-Os is
> -O2 plus optimize for size really).

Thanks. Is it possible to enable vrp with -ftree-vrp at -O0 level? Therefore the user can get this warning even when the code is not optimized?
Comment 9 Jakub Jelinek 2014-02-09 06:39:11 UTC
No.  VRP isn't really a cheap pass and for -O0 the most important thing is compile time speed.  GCC has never guaranteed the same warnings between optimization levels, for frontend warnings it is sometimes possible to have the same warnings, but for middle-end warnings it is not possible and never a goal.
Think say about uninitialized warnings, some of them heavily depend on which functions are inlined and which are not.