This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] handle multiple flexible array members (PR 83588)
- From: Martin Sebor <msebor at gmail dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>, Jason Merrill <jason at redhat dot com>
- Date: Sun, 14 Jan 2018 16:47:17 -0700
- Subject: [PATCH] handle multiple flexible array members (PR 83588)
- Authentication-results: sourceware.org; auth=none
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[];
+};