https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69696
Bug ID: 69696 Summary: incorrect initialization of block-scope flexible array members Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- As pointed in the following discussion https://gcc.gnu.org/ml/gcc-patches/2016-02/msg00420.html, g++ allows local structs with flexible array members to be initialized on definition but then allocates the arrays in a way that overlaps other local variables, leading to data corruption. In C mode, GCC rejects initialization of such structs (this was done to fix bug 28865). G++ should either also reject initialiation of such structs, or it should do it without this overlapping problem. Note that bug 68489 is also related to this problem, as is bug 69338. The following test case shows that while structures containing flexible array members and having static or thread storage duration are initialized correctly, those having automatic storage duration are not. $ cat t.c && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -Wall -Wextra -Wpedantic -xc++ t.c && ./a.out enum { X = 12345678, Y = 87654321 }; struct A { int n, a []; }; struct A a0 = { 1, { 2, 3, 4 } }; void print (const int *i, struct A *a, const int *j) { __builtin_printf ("\ni = %i\n" "a = { %i, { %i, %i, %i }\n" "j = %i\n", *i, a->n, a->a[0], a->a[1], a->a[2], *j); if (*i != X || *j != Y || a->a[0] != 2 || a->a[1] != 3 || a->a[2] != 4) __builtin_abort (); } int main () { { static int i = X; static struct A a = { 1, { 2, 3, 4 } }; static int j = Y; print (&i, &a, &j); } { __thread int i = X; __thread struct A a = { 1, { 2, 3, 4 } }; __thread int j = Y; print (&i, &a, &j); } { int i = X; struct A a = { 1, { 2, 3, 4 } }; int j = Y; print (&i, &a, &j); } } t.c:4:32: warning: initialization of a flexible array member [-Wpedantic] struct A a0 = { 1, { 2, 3, 4 } }; ^ t.c: In function ‘int main()’: t.c:22:46: warning: initialization of a flexible array member [-Wpedantic] static struct A a = { 1, { 2, 3, 4 } }; ^ t.c:28:22: warning: function-scope ‘i’ implicitly auto and declared ‘__thread’ __thread int i = X; ^ t.c:29:27: warning: function-scope ‘a’ implicitly auto and declared ‘__thread’ __thread struct A a = { 1, { 2, 3, 4 } }; ^ t.c:29:48: warning: initialization of a flexible array member [-Wpedantic] __thread struct A a = { 1, { 2, 3, 4 } }; ^ t.c:30:22: warning: function-scope ‘j’ implicitly auto and declared ‘__thread’ __thread int j = Y; ^ t.c:36:39: warning: initialization of a flexible array member [-Wpedantic] struct A a = { 1, { 2, 3, 4 } }; ^ i = 12345678 a = { 1, { 2, 3, 4 } j = 87654321 i = 12345678 a = { 1, { 2, 3, 4 } j = 87654321 i = 4 a = { 1, { 2, 3, 4 } j = 87654321 Aborted (core dumped)