Message ID | 20161207202622.GJ2337@redhat.com |
---|---|
State | New |
Headers | show |
If the problem is the member initializer, we can diagnose that directly rather than wait until we're in a constructor. On Wed, Dec 7, 2016 at 3:26 PM, Marek Polacek <polacek@redhat.com> wrote: > We were crashing in finish_expr_stmt here: > 676 /* If we ran into a problem, make sure we complained. */ > 677 gcc_assert (expr != error_mark_node || seen_error ()); > Well, we ran into a problem, but never raised an error. The problem was that > we couldn't determine the max index of the array when default-initizalizing the > members (at the beginning of cp_parser_ctor_initializer_opt). Jason's > preference seems to be to disable initialization of a flexible array member in > a constructor and that is what this patch attempts to do. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2016-12-07 Marek Polacek <polacek@redhat.com> > > PR c++/72775 > * init.c (perform_member_init): Diagnose initialization of a flexible > array member in a constructor. > > * g++.dg/ext/flexary20.C: New. > > diff --git gcc/cp/init.c gcc/cp/init.c > index b4b6cdb..01009c9 100644 > --- gcc/cp/init.c > +++ gcc/cp/init.c > @@ -800,6 +800,10 @@ perform_member_init (tree member, tree init) > in that case. */ > init = build_x_compound_expr_from_list (init, ELK_MEM_INIT, > tf_warning_or_error); > + else if (TREE_CODE (type) == ARRAY_TYPE > + && TYPE_DOMAIN (type) == NULL_TREE) > + error_at (DECL_SOURCE_LOCATION (member), > + "initialization of a flexible array member in a constructor"); > > if (init) > finish_expr_stmt (cp_build_modify_expr (input_location, decl, > diff --git gcc/testsuite/g++.dg/ext/flexary20.C gcc/testsuite/g++.dg/ext/flexary20.C > index e69de29..ff97b06 100644 > --- gcc/testsuite/g++.dg/ext/flexary20.C > +++ gcc/testsuite/g++.dg/ext/flexary20.C > @@ -0,0 +1,49 @@ > +// PR c++/72775 > +// { dg-do compile { target c++11 } } > +// { dg-options -Wno-pedantic } > + > +struct S { > + int i; > + char a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } > + S () {} > +}; > + > +struct T { > + int i; > + char a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } > +}; > + > +struct U { > + int i; > + char a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } > + U (); > +}; > + > +U::U() {} > + > +int > +main () > +{ > + struct T t; > +} > + > +struct V { > + int i; > + struct W { > + int j; > + char a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } > + } w; > + V () {} > +}; > + > +template <class T> > +struct X { > + int i; > + T a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } > +}; > + > +void > +fn () > +{ > + struct X<char> x; > +} > > Marek
On 12/08/2016 01:05 PM, Jason Merrill wrote: > If the problem is the member initializer, we can diagnose that > directly rather than wait until we're in a constructor. What about: struct Foo { int a; char ary[]; Foo () : ary ("bob"){} }; ? That ICEs in the same way. nathan
diff --git gcc/cp/init.c gcc/cp/init.c index b4b6cdb..01009c9 100644 --- gcc/cp/init.c +++ gcc/cp/init.c @@ -800,6 +800,10 @@ perform_member_init (tree member, tree init) in that case. */ init = build_x_compound_expr_from_list (init, ELK_MEM_INIT, tf_warning_or_error); + else if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_DOMAIN (type) == NULL_TREE) + error_at (DECL_SOURCE_LOCATION (member), + "initialization of a flexible array member in a constructor"); if (init) finish_expr_stmt (cp_build_modify_expr (input_location, decl, diff --git gcc/testsuite/g++.dg/ext/flexary20.C gcc/testsuite/g++.dg/ext/flexary20.C index e69de29..ff97b06 100644 --- gcc/testsuite/g++.dg/ext/flexary20.C +++ gcc/testsuite/g++.dg/ext/flexary20.C @@ -0,0 +1,49 @@ +// PR c++/72775 +// { dg-do compile { target c++11 } } +// { dg-options -Wno-pedantic } + +struct S { + int i; + char a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } + S () {} +}; + +struct T { + int i; + char a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } +}; + +struct U { + int i; + char a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } + U (); +}; + +U::U() {} + +int +main () +{ + struct T t; +} + +struct V { + int i; + struct W { + int j; + char a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } + } w; + V () {} +}; + +template <class T> +struct X { + int i; + T a[] = "foo"; // { dg-error "initialization of a flexible array member in a constructor" } +}; + +void +fn () +{ + struct X<char> x; +}