https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88578
Bug ID: 88578 Summary: Static C++ objects with flexible array members overlap when initializes are non-const Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: bernd.edlinger at hotmail dot de Target Milestone: --- A modified version of flexary13.C fails an assertion when compiled with -O0 $ cat flexary13.C // { dg-do compile } // { dg-options -Wno-pedantic } #define STR(s) #s #define ASSERT(exp) \ ((exp) ? (void)0 : (void)(__builtin_printf ("%s:%i: assertion %s failed\n", \ __FILE__, __LINE__, STR(exp)), \ __builtin_abort ())) struct Ax { int n, a[]; }; struct AAx { int i; Ax ax; }; int i = 12345678; int main () { { Ax s = { 0 }; ASSERT (s.n == 0); } { static Ax s = { 0, { } }; // dg-warning "initialization of a flexible array member" } ASSERT (s.n == 0); } { static Ax s = { 1, { 2 } }; // dg-warning "initialization of a flexible array member" } ASSERT (s.n == 1 && s.a [0] == 2); } { static Ax s = { 2, { 3, 4 } }; // dg-warning "initialization of a flexible array member" } ASSERT (s.n = 2 && s.a [0] == 3 && s.a [1] == 4); } { static Ax s = { 123, i }; // dg-warning "initialization of a flexible array member" } ASSERT (s.n == 123 && s.a [0] == i); } { static Ax s = { 456, { i } }; // dg-warning "initialization of a flexible array member" } ASSERT (s.n == 456 && s.a [0] == i); } { int j = i + 1, k = j + 1; static Ax s = { 3, { i, j, k } }; // dg-warning "initialization of a flexible array member" } ASSERT (s.n == 3 && s.a [0] == i && s.a [1] == j && s.a [2] == k); } { AAx s = { 1, { 2 } }; // dg-warning "initialization of a flexible array member" } ASSERT (s.i == 1 && s.ax.n == 2); } } $ g++ -O0 flexary13.C $ ./a.out flexary13.C:44: assertion s.n == 456 && s.a [0] == i failed Aborted (core dumped) debugging shows that s.n == 12345678 reason is that in the case where flexible array members are initialized with non-constant values (a C++ extension over C which rejects such code) The static objects are allocated without the flexible part: _ZZ4mainE1s_2: .long 123 .local _ZGVZ4mainE1s_2 .comm _ZGVZ4mainE1s_2,8,8 .align 4 .type _ZZ4mainE1s_3, @object .size _ZZ4mainE1s_3, 4 _ZZ4mainE1s_3: .long 456 .local _ZGVZ4mainE1s_3 .comm _ZGVZ4mainE1s_3,8,8 .align 4 .type _ZZ4mainE1s_4, @object .size _ZZ4mainE1s_4, 4 In higher optimization levels the objects still overlap, but the assertion does not fire, which probably indicates that it is ineffective (optimized away).