On Thu, Dec 08, 2016 at 02:56:56PM -0500, Nathan Sidwell wrote: > 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.
Given the above, we can't diagnose member initializers directly, it seems. So the following is the latest version, with Nathan's testcase. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2016-12-14 Marek Polacek <pola...@redhat.com> PR c++/72775 * init.c (perform_member_init): Diagnose initialization of a flexible array member in a constructor. * g++.dg/ext/flexary12.C: Adjust dg-error. * g++.dg/ext/flexary20.C: New. * g++.dg/ext/flexary21.C: New. diff --git gcc/cp/init.c gcc/cp/init.c index b4b6cdb..57a05de 100644 --- gcc/cp/init.c +++ gcc/cp/init.c @@ -800,6 +800,11 @@ 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); + if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_DOMAIN (type) == NULL_TREE + && init != 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/flexary12.C gcc/testsuite/g++.dg/ext/flexary12.C index 3d8c805..7ebf43f 100644 --- gcc/testsuite/g++.dg/ext/flexary12.C +++ gcc/testsuite/g++.dg/ext/flexary12.C @@ -40,7 +40,7 @@ void f2 () } struct D { - int a []; // { dg-error "flexible array member .D::a. in an otherwise empty .struct D." } + int a []; // { dg-error "initialization of a flexible|flexible array member .D::a. in an otherwise empty .struct D." } D (); }; 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; +} diff --git gcc/testsuite/g++.dg/ext/flexary21.C gcc/testsuite/g++.dg/ext/flexary21.C index e69de29..1b19f6c 100644 --- gcc/testsuite/g++.dg/ext/flexary21.C +++ gcc/testsuite/g++.dg/ext/flexary21.C @@ -0,0 +1,15 @@ +// PR c++/72775 +// { dg-do compile { target c++11 } } +// { dg-options -Wno-pedantic } + +struct S { + int i; + char a[]; // { dg-error "initialization of a flexible array member in a constructor" } + S () : a("bob") {} +}; + +struct T { + int i; + char a[] = "bob"; // { dg-error "initialization of a flexible array member in a constructor" } + T () : a("bob") {} +}; Marek