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]; ^
Working on a patch.
No working on the patch anymore.
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[]; ^