diff mbox

C++ PATCH to reject initializating flexible array members in constructors (PR c++/72775)

Message ID 20161214170109.GI2337@redhat.com
State New
Headers show

Commit Message

Marek Polacek Dec. 14, 2016, 5:01 p.m. UTC
On Wed, Dec 14, 2016 at 11:30:17AM -0500, Jason Merrill wrote:
> On Wed, Dec 14, 2016 at 10:39 AM, Marek Polacek <polacek@redhat.com> wrote:
> > +      if (TREE_CODE (type) == ARRAY_TYPE
> > +         && TYPE_DOMAIN (type) == NULL_TREE
> > +         && init != NULL_TREE)
> > +       error_at (DECL_SOURCE_LOCATION (current_function_decl),
> > +                 "member initializer for flexible array member");
> 
> Sorry to keep nitpicking, but let's also point to the member in
> question with a follow-on inform, as with some other diagnostics in
> perform_member_init.

How about this then?

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2016-12-14  Marek Polacek  <polacek@redhat.com>

	PR c++/72775
	* init.c (perform_member_init): Diagnose member initializer for
	flexible array member. 

	* g++.dg/ext/flexary12.C: Adjust dg-error.
	* g++.dg/ext/flexary20.C: New.
	* g++.dg/ext/flexary21.C: New.


	Marek

Comments

Jason Merrill Dec. 14, 2016, 8:36 p.m. UTC | #1
OK, thanks.

On Wed, Dec 14, 2016 at 12:01 PM, Marek Polacek <polacek@redhat.com> wrote:
> On Wed, Dec 14, 2016 at 11:30:17AM -0500, Jason Merrill wrote:
>> On Wed, Dec 14, 2016 at 10:39 AM, Marek Polacek <polacek@redhat.com> wrote:
>> > +      if (TREE_CODE (type) == ARRAY_TYPE
>> > +         && TYPE_DOMAIN (type) == NULL_TREE
>> > +         && init != NULL_TREE)
>> > +       error_at (DECL_SOURCE_LOCATION (current_function_decl),
>> > +                 "member initializer for flexible array member");
>>
>> Sorry to keep nitpicking, but let's also point to the member in
>> question with a follow-on inform, as with some other diagnostics in
>> perform_member_init.
>
> How about this then?
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2016-12-14  Marek Polacek  <polacek@redhat.com>
>
>         PR c++/72775
>         * init.c (perform_member_init): Diagnose member initializer for
>         flexible array member.
>
>         * 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..47428b9 100644
> --- gcc/cp/init.c
> +++ gcc/cp/init.c
> @@ -800,6 +800,14 @@ 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 (current_function_decl),
> +                   "member initializer for flexible array member");
> +         inform (DECL_SOURCE_LOCATION (member), "%q#D initialized", member);
> +       }
>
>        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..db80bf4 100644
> --- gcc/testsuite/g++.dg/ext/flexary12.C
> +++ gcc/testsuite/g++.dg/ext/flexary12.C
> @@ -44,7 +44,7 @@ struct D {
>    D ();
>  };
>
> -D::D ():
> +D::D ():    // { dg-error "member initializer for flexible array member" }
>    a ("c")   // { dg-error "incompatible types in assignment of .const char \\\[2\\\]. to .int \\\[\\\]." }
>  { }
>
> diff --git gcc/testsuite/g++.dg/ext/flexary20.C gcc/testsuite/g++.dg/ext/flexary20.C
> index e69de29..2c8ab29 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";
> +  S () {} // { dg-error "member initializer for flexible array member" }
> +};
> +
> +struct T { // { dg-error "member initializer for flexible array member" }
> +  int i;
> +  char a[] = "foo";
> +};
> +
> +struct U {
> +  int i;
> +  char a[] = "foo";
> +  U ();
> +};
> +
> +U::U() {} // { dg-error "member initializer for flexible array member" }
> +
> +int
> +main ()
> +{
> +  struct T t;
> +}
> +
> +struct V {
> +  int i;
> +  struct W { // { dg-error "member initializer for flexible array member" }
> +    int j;
> +    char a[] = "foo";
> +  } w;
> +  V () {}
> +};
> +
> +template <class T>
> +struct X { // { dg-error "member initializer for flexible array member" }
> +  int i;
> +  T a[] = "foo";
> +};
> +
> +void
> +fn ()
> +{
> +  struct X<char> x;
> +}
> diff --git gcc/testsuite/g++.dg/ext/flexary21.C gcc/testsuite/g++.dg/ext/flexary21.C
> index e69de29..5675bf6 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[];
> +  S () : a("bob") {} // { dg-error "member initializer for flexible array member" }
> +};
> +
> +struct T {
> +  int i;
> +  char a[] = "bob";
> +  T () : a("bob") {} // { dg-error "member initializer for flexible array member" }
> +};
>
>         Marek
diff mbox

Patch

diff --git gcc/cp/init.c gcc/cp/init.c
index b4b6cdb..47428b9 100644
--- gcc/cp/init.c
+++ gcc/cp/init.c
@@ -800,6 +800,14 @@  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 (current_function_decl),
+		    "member initializer for flexible array member");
+	  inform (DECL_SOURCE_LOCATION (member), "%q#D initialized", member);
+	}
 
       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..db80bf4 100644
--- gcc/testsuite/g++.dg/ext/flexary12.C
+++ gcc/testsuite/g++.dg/ext/flexary12.C
@@ -44,7 +44,7 @@  struct D {
   D ();
 };
 
-D::D ():
+D::D ():    // { dg-error "member initializer for flexible array member" }
   a ("c")   // { dg-error "incompatible types in assignment of .const char \\\[2\\\]. to .int \\\[\\\]." }
 { }
 
diff --git gcc/testsuite/g++.dg/ext/flexary20.C gcc/testsuite/g++.dg/ext/flexary20.C
index e69de29..2c8ab29 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";
+  S () {} // { dg-error "member initializer for flexible array member" }
+};
+
+struct T { // { dg-error "member initializer for flexible array member" }
+  int i;
+  char a[] = "foo";
+};
+
+struct U {
+  int i;
+  char a[] = "foo";
+  U ();
+};
+
+U::U() {} // { dg-error "member initializer for flexible array member" }
+
+int
+main ()
+{
+  struct T t;
+}
+
+struct V {
+  int i;
+  struct W { // { dg-error "member initializer for flexible array member" }
+    int j;
+    char a[] = "foo";
+  } w;
+  V () {}
+};
+
+template <class T>
+struct X { // { dg-error "member initializer for flexible array member" }
+  int i;
+  T a[] = "foo";
+};
+
+void
+fn ()
+{
+  struct X<char> x;
+}
diff --git gcc/testsuite/g++.dg/ext/flexary21.C gcc/testsuite/g++.dg/ext/flexary21.C
index e69de29..5675bf6 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[];
+  S () : a("bob") {} // { dg-error "member initializer for flexible array member" }
+};
+
+struct T {
+  int i;
+  char a[] = "bob";
+  T () : a("bob") {} // { dg-error "member initializer for flexible array member" }
+};