Bug 58101 - Wrong out-of-bounds warning under -Os
Summary: Wrong out-of-bounds warning under -Os
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.8.2
: P3 major
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2013-08-07 18:31 UTC by Luis A Lozano
Modified: 2021-12-23 06:36 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.9.3, 5.1.0, 6.0
Last reconfirmed: 2015-12-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Luis A Lozano 2013-08-07 18:31:10 UTC
The following test case generates a wrong "out-of-bounds" warning. 
This problem only happens under -Os

gcc test.i -c -Os -Werror -Wall

 In function ‘rcu_init_lal’:
/home/llozano/trash/min_rcutree.i:17:13: error: array subscript is above array bounds [-Werror=array-bounds]
   rsp->level[i] = rsp->level[i - 1] + rsp->levelcnt[i - 1];

rcu_num_levels is never larger than 1. So the code inside the loop is never executed. 

test.i:
---
extern int rcu_num_lvls;
int rcu_num_lvls = 1;

struct rcu_node {
};

struct rcu_state {
 struct rcu_node *level[1];
 int levelcnt[4 + 1];
};

void rcu_init_lal(struct rcu_state *rsp)
{
 int i;

 for (i = 1; i < rcu_num_lvls; i++)
  rsp->level[i] = rsp->level[i - 1] + rsp->levelcnt[i - 1];
}
Comment 1 Luis A Lozano 2013-08-07 22:54:05 UTC
Raising priority of this issue. 
This problem was found while build the ChromOS linux kernel. 
Most probably this will be found by other platfroms using the linux kernel.
Comment 2 Marek Polacek 2013-08-08 06:41:31 UTC
Perhaps a dup of PR41847.  Fails even with -O2, -O3, -Ofast, no only -Os.  -fno-tree-vrp makes it go away...
Comment 3 Luis A Lozano 2013-08-08 20:46:08 UTC
(In reply to Marek Polacek from comment #2)
> Perhaps a dup of PR41847.  Fails even with -O2, -O3, -Ofast, no only -Os. 
> -fno-tree-vrp makes it go away...

I dont think it is a duplicate of this issue. 
This problem does not happen with GCC 4.7.2
Comment 4 Mikhail Veltishchev 2014-04-08 15:24:52 UTC
Luis, why do you state that "rcu_num_levels is never larger than 1", this cannot be proved as this variable is not const and can change its value (e.g. in another thread).
Comment 5 Martin Sebor 2015-12-16 02:58:55 UTC
Confirmed with 5.1 and 6.0.  A simpler test case:

$ cat a.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc -shared-libgcc -B/home/msebor/build/gcc-trunk-svn/gcc -Os -S -Wall -o/dev/null a.c
int a [1];

void foo (int n)
{
   for (int i = 1; i < n; i++)
       a [i] = a [i - 1];
}

a.c: In function ‘foo’:
a.c:6:10: warning: array subscript is above array bounds [-Warray-bounds]
        a [i] = a [i - 1];
        ~~^~~
Comment 6 Andrew Pinski 2021-12-23 06:36:57 UTC
Further reduced:
int a [1];

void foo (int n)
{
   if (n <= 1) return;
   int i = 1;
   a [i] = a [i - 1];
}

This is one of these false positives warning where we should maybe not warn but instead just change the code to be a trap.

Note in the original testcase, GCC is able to remove the loop and just change it to one statement. That is part of the reason for the warning even.

clang does not warn about the above because they only warn for the literal a[1] case.