A very common pattern due to pedantic C89, C90, and C++ compatibility is to declare an array of size 1 when having a structure with a variable sized member at the end. GCC's memory protection extensions, however, work in a way that only zero/variable sized members are treated in such way that their bounds are not explicitly checked (https://gcc.gnu.org/wiki/Intel%20MPX%20support%20in%20the%20GCC%20compiler#line-142). This makes it impossible to use existing code with MPX checks without changes that go through large amount of header files that use this pattern of arrays size 1. To demonstrate this issue, here are 3 different ways to indicate structures with a variable sized array at the end of the structure: typedef struct struktura1 { long len; char data[]; } struktura1; typedef struct struktura2 { long len; char data[0]; } struktura2; typedef struct struktura3 { long len; char data[1] __attribute__((bnd_variable_size)); } struktura3; If we compile them with different standards and warning levels, we'll get these kind of results: $ gcc-5.2.0 --std=c89 -pedantic tst.c tst.c:3:10: warning: ISO C90 does not support flexible array members [-Wpedantic] char data[]; ^ tst.c:8:10: warning: ISO C forbids zero-size array ‘data’ [-Wpedantic] char data[0]; $ gcc-5.2.0 -xc++ --std=c++14 -pedantic tst.c tst.c:3:15: warning: ISO C++ forbids zero-size array ‘data’ [-Wpedantic] char data[]; ^ tst.c:8:16: warning: ISO C++ forbids zero-size array ‘data’ [-Wpedantic] char data[0]; $ gcc-4.8 --std=c11 -pedantic tst.c tst.c:8:10: warning: ISO C forbids zero-size array ‘data’ [-Wpedantic] char data[0]; ^ tst.c:13:5: warning: ‘bnd_variable_size’ attribute directive ignored [-Wattributes] char data[1] __attribute__((bnd_variable_size)); ^ Not to mention that a lot of code is compiled with other compilers than GCC that don't know about "bnd_variable_size" attribute, so making the code shown above to be compatible with different compilers and also having MPX checks in place requires some macro magic depending on which compiler is in use and which standard the compilation is done against. GCC should ignore or have an option to ignore bound checks for arrays of size 1 at the end of the structure so that just trying out MPX support wouldn't need large scale changes to existing code bases.
MPX should just behave like the rest of GCC treating _all_ trailing arrays as possibly flexible.
GCC 6.2.1 is still affected by this. In C99 we can get away with flexible array members, but this feature is unfortunately not defined in the C++ specification. The idiom with an array of length 1 is quite common, is it possible to detect that situation and relax the boundaries?
Addressed in ------------------------------------------------------------------------ r243936 | aivchenk | 2016-12-27 16:31:43 +0300 (Tue, 27 Dec 2016) | 18 lines 2016-12-27 Alexander Ivchenko <alexander.ivchenko@intel.com> * c-family/c.opt (flag_chkp_flexible_struct_trailing_arrays): Add new option. (fchkp-narrow-to-innermost-array): Fix typo. * doc/cpp.texi (flag_chkp_flexible_struct_trailing_arrays): Ditto. * tree-chkp.c (chkp_may_narrow_to_field ): Forbid narrowing when flag_chkp_flexible_struct_trailing_arrays is used and the field is the last array field in the structure. 2016-12-27 Alexander Ivchenko <alexander.ivchenko@intel.com> * gcc.target/i386/mpx/vla-trailing-1-lbv.c: New test. * gcc.target/i386/mpx/vla-trailing-1-nov.c: Ditto. * gcc.target/i386/mpx/vla-trailing-1-ubv.c: Ditto. The new option -fchkp-flexible-struct-trailing-arrays will allow to treat all trailing arrays in structures as possibly flexible. The bug can be closed
The issue is not solved, let's consider: $ cat /tmp/chkp.ii typedef struct a *b; struct a { struct { int e[1]; } f; }; int g(b ptr) { return ptr->f.e[1]; } $ ./xgcc -B. /tmp/chkp.ii -Werror -c -mmpx -fcheck-pointer-bounds -O1 -Wall -fchkp-flexible-struct-trailing-arrays /tmp/chkp.ii: In function ‘int g.chkp(b, \xe2\x80\x98pointer_bounds_typ\xe2\x80\x99 not supported by dump_type#<type error>, void, ...)’: /tmp/chkp.ii:9:20: error: memory access check always fail [-Werror=chkp] return ptr->f.e[1]; ^ cc1plus: all warnings being treated as errors It's wrong and reason is explained in Richi's email: https://gcc.gnu.org/ml/gcc-patches/2017-01/msg00172.html I'm testing the patch.
Author: marxin Date: Tue Mar 7 14:12:52 2017 New Revision: 245951 URL: https://gcc.gnu.org/viewcvs?rev=245951&root=gcc&view=rev Log: Use array_at_struct_end_p in tree-chkp.c (PR middle-end/68270). 2017-03-07 Martin Liska <mliska@suse.cz> PR middle-end/68270 * tree-chkp.c (chkp_may_narrow_to_field): Add new argument ref. Use array_at_struct_end_p instead of DECL_CHAIN (field). (chkp_narrow_bounds_for_field): Likewise. (chkp_parse_array_and_component_ref): Pass one more argument to call. 2017-03-07 Martin Liska <mliska@suse.cz> PR middle-end/68270 * g++.dg/pr68270.C: New test. Added: trunk/gcc/testsuite/g++.dg/pr68270.C Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-chkp.c
Fixed on trunk.
As the flag fchkp-flexible-struct-trailing-arrays was introduced in GCC7, the issue can be closed as resolved.