Bug 68354 - -Warray-bounds on a flexible array member in C++
Summary: -Warray-bounds on a flexible array member in C++
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: ---
Assignee: Martin Sebor
URL:
Keywords: diagnostic
Depends on:
Blocks: flexmembers
  Show dependency treegraph
 
Reported: 2015-11-15 02:09 UTC by Martin Sebor
Modified: 2017-03-20 21:20 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 7.0
Known to fail: 5.3.0, 6.3.0
Last reconfirmed: 2015-11-15 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2015-11-15 02:09:42 UTC
In C++ mode (but not in C mode), g++ silently (without -Wpedantic) accepts both a definition of a struct with a flexible array member and an object of such a type without an initializer but issues a warning for accesses to the array (see below).  Debugging reveals that unlike the C front end, the C++ front end sets the bounds on flexible arrays to [0, SIZE_MAX].  The code in check_array_ref in tree-vrp.c then trips up on such an array because it first assumes that flexible arrays have no bounds, and further assumes that no array has an upper bound of SIZE_MAX when adding one to the bound.  When the computation wraps around to zero, the function incorrectly deduces that the array is empty and issues a warning.

It seems wrong for the C++ front end to set the upper bound to SIZE_MAX for any array.  First, because GCC itself assumes that no object is larger than SIZE_MAX / 2.  Second, when the size of the array element is greater than 1 as in the case below, even the most permissive upper bound cannot be SIZE_MAX.

$ cat u.cpp && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -O2 -S -Wall -Wextra -o/dev/null u.cpp 
struct S {
    int n;
    int a[];
} s;

int i;

void f ()
{
    i = s.a [0];
}

u.cpp: In function ‘void f()’:
u.cpp:10:15: warning: array subscript is above array bounds [-Warray-bounds]
     i = s.a [0];
               ^
Comment 1 Martin Sebor 2015-11-15 02:10:20 UTC
Working on a patch.
Comment 2 Martin Sebor 2017-03-20 21:07:11 UTC
No working on the patch anymore.
Comment 3 Martin Sebor 2017-03-20 21:20:29 UTC
With GCC 7.0 and 6 the -Warray-bounds warning is gone.  With GCC 7 and 5 (but not 6) the flexible array member is diagnosed with -Wpedantic.

The internal representation of flexible array members has also changed with r231665: such members have a null domain, which is likely what has eliminated the  -Warray-bounds warning.

With this, although there still are many outstanding problems with flexible array members (see the meta-bug 69698), I think this bug can be resolved as fixed.

$ cat y.c && gcc -O2 -S -Wall -Wextra -Wpedantic -xc++ y.c
struct S {
    int n;
    int a[];
} s;

int i;

void f ()
{
    i = s.a [0];
}
y.c:3:11: warning: ISO C++ forbids flexible array member ‘a’ [-Wpedantic]
     int a[];
           ^