The attached patch fixes PR c++/83588 - struct with two flexible arrays causes an internal compiler error. The ICE is caused by the same assertion in varasm.c that has led to other similar reports in the past:
/* Given a non-empty initialization, this field had better be last. Given a flexible array member, the next field on the chain is a TYPE_DECL of the enclosing struct. */ const_tree next = DECL_CHAIN (local->field); gcc_assert (!fieldsize || !next || TREE_CODE (next) != FIELD_DECL); The fix is simply to also detect when a class defines more than one flexible array member and treat the subsequent array as any other member, and reject such class definitions to make sure they never reach the assertion above. Martin
PR c++/83588 - struct with two flexible arrays causes an internal compiler error gcc/cp/ChangeLog: PR c++/83588 * class.c (find_flexarrays): Make a record of multiple flexible array members. gcc/testsuite/ChangeLog: PR c++/83588 * g++.dg/ext/flexary28.C: New test. Index: gcc/cp/class.c =================================================================== --- gcc/cp/class.c (revision 256674) +++ gcc/cp/class.c (working copy) @@ -6566,14 +6566,17 @@ find_flexarrays (tree t, flexmems_t *fmem, bool ba /* Flexible array members have no upper bound. */ if (fmem->array) { - /* Replace the zero-length array if it's been stored and - reset the after pointer. */ if (TYPE_DOMAIN (TREE_TYPE (fmem->array))) { + /* Replace the zero-length array if it's been stored and + reset the after pointer. */ fmem->after[bool (pun)] = NULL_TREE; fmem->array = fld; fmem->enclosing = pstr; } + else if (!fmem->after[bool (pun)]) + /* Make a record of another flexible array member. */ + fmem->after[bool (pun)] = fld; } else { Index: gcc/testsuite/g++.dg/ext/flexary28.C =================================================================== --- gcc/testsuite/g++.dg/ext/flexary28.C (nonexistent) +++ gcc/testsuite/g++.dg/ext/flexary28.C (working copy) @@ -0,0 +1,46 @@ +// PR c++/83588 - struct with two flexible arrays causes an internal compiler +// error +// { dg-do compile } +// { dg-options "-Wno-pedantic" } + +struct A { + int i; + int a[]; // { dg-error "flexible array member .A::a. not at end of .struct A." } + int b[]; +}; + +struct B { + int i; + int a[]; // { dg-error "flexible array member .B::a. not at end of .struct B." } + int j; + int b[][2]; +}; + +struct C { + int i; + struct { + int a[]; // { dg-error "flexible array member .C::<unnamed struct>::a. not at end of .struct C." } + }; + int b[]; +}; + +struct D { + int i; + struct { + int a[]; // { dg-error "flexible array member .D::<unnamed struct>::a. not at end of .struct D." } + } b[]; + int c[]; +}; + +struct E { + int i; + int a[0]; + int b[]; // { dg-error "flexible array member .E::b. not at end of .struct E." } + int d[]; +}; + +struct F { + int i; + int a[]; // { dg-error "flexible array member .F::a. not at end of .struct F." } + int b[], c[], d[]; +};