On Mon, Aug 08, 2016 at 11:04:32AM +0000, Joseph Myers wrote: > On Sat, 6 Aug 2016, Jakub Jelinek wrote: > > > --- gcc/testsuite/gcc.dg/pr72816.c.jj 2016-08-06 13:06:45.046003282 > > +0200 > > +++ gcc/testsuite/gcc.dg/pr72816.c 2016-08-06 13:07:57.217093845 +0200 > > @@ -0,0 +1,9 @@ > > +/* PR c/72816 */ > > +/* { dg-do compile } */ > > +/* { dg-options "-std=gnu11" } */ > > + > > +typedef const int A[]; > > +struct S { > > + int a; > > + A b; /* { dg-error "array size missing" } */ > > +}; > > As far as I can tell, this is actually valid code that should not produce > an error; the type of a flexible array member can be given by a typedef, > and I see nothing to disallow it being given by a typedef for an array of > qualified type. Note that both the version of this test without const, > and the version with const but not using a typedef, are accepted.
Indeed. The following untested patch fixes the issue for me. The problem was that when we create the distinct type with TYPE_DOMAIN [0:], if TYPE_MAIN_VARIANT (orig_qual_type) is TYPE_MAIN_VARIANT (type) before we do this, then c_build_qualified_type will return that orig_qual_type and the TYPE_DOMAIN [0:] is gone again. I think for orig_qual_indirect > 0 we are ok, in that case c_build_qualified_type will never return that and as the flexible array member is the outermost ARRAY_TYPE, we should be fine. But perhaps if (orig_qual_indirect > 0 && orig_qual_type), we never reach the flexible array member through typedef else if, so perhaps just unconditional orig_qual_type = NULL_TREE; in that else if would work too. Which of these two versions do you prefer (or something else)? Shall I revert the stor-layout.c change which might be unnecessary (though shouldn't hurt)? 2016-08-10 Jakub Jelinek <ja...@redhat.com> PR c/72816 * c-decl.c (grokdeclarator): When adding TYPE_DOMAIN for flexible array member through typedef, for orig_qual_indirect == 0 clear orig_qual_type. * gcc.dg/pr72816.c: New test. --- gcc/c/c-decl.c.jj 2016-08-06 12:11:47.000000000 +0200 +++ gcc/c/c-decl.c 2016-08-10 17:07:10.675144603 +0200 @@ -6710,6 +6710,8 @@ grokdeclarator (const struct c_declarato type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node, NULL_TREE); + if (orig_qual_indirect == 0) + orig_qual_type = NULL_TREE; } type = c_build_qualified_type (type, type_quals, orig_qual_type, orig_qual_indirect); --- gcc/testsuite/gcc.dg/pr72816.c.jj 2016-08-07 11:48:34.000000000 +0200 +++ gcc/testsuite/gcc.dg/pr72816.c 2016-08-10 17:08:21.153266419 +0200 @@ -5,5 +5,5 @@ typedef const int A[]; struct S { int a; - A b; /* { dg-error "array size missing" } */ + A b; }; Jakub