re PR c/64417 ([SH] FAIL: gcc.c-torture/compile/pr28865.c -O0 (test for excess...
authorMarek Polacek <polacek@redhat.com>
Wed, 7 Jan 2015 08:19:48 +0000 (08:19 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 7 Jan 2015 08:19:48 +0000 (08:19 +0000)
PR c/64417
c/
* c-typeck.c (process_init_element): Disallow initialization of
a flexible array member with a string constant if the structure
is in an array.
testsuite/
* gcc.c-torture/compile/pr28865.c: Add dg-errors.
* gcc.dg/pr64417.c: New test.

From-SVN: r219278

gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr28865.c
gcc/testsuite/gcc.dg/pr64417.c [new file with mode: 0644]

index d6b228902f95bf5a21d841d2fce8e50ef0218a0f..357d2c4d376c4488cd5799e0379a604adefbe0e8 100644 (file)
@@ -1,3 +1,10 @@
+2015-01-07  Marek Polacek  <polacek@redhat.com>
+
+       PR c/64417
+       * c-typeck.c (process_init_element): Disallow initialization of
+       a flexible array member with a string constant if the structure
+       is in an array.
+
 2015-01-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR sanitizer/64344
index 0db43cc1b63226d1e90e5f7e100d5e314e63d658..38ba9b8ede626d7d147a56cf5905987299c94d7f 100644 (file)
@@ -8809,6 +8809,33 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
              break;
            }
 
+         /* Error for initialization of a flexible array member with
+            a string constant if the structure is in an array.  E.g.:
+            struct S { int x; char y[]; };
+            struct S s[] = { { 1, "foo" } };
+            is invalid.  */
+         if (string_flag
+             && fieldcode == ARRAY_TYPE
+             && constructor_depth > 1
+             && TYPE_SIZE (fieldtype) == NULL_TREE
+             && DECL_CHAIN (constructor_fields) == NULL_TREE)
+           {
+             bool in_array_p = false;
+             for (struct constructor_stack *p = constructor_stack;
+                  p && p->type; p = p->next)
+               if (TREE_CODE (p->type) == ARRAY_TYPE)
+                 {
+                   in_array_p = true;
+                   break;
+                 }
+             if (in_array_p)
+               {
+                 error_init (loc, "initialization of flexible array "
+                             "member in a nested context");
+                 break;
+               }
+           }
+
          /* Accept a string constant to initialize a subarray.  */
          if (value.value != 0
              && fieldcode == ARRAY_TYPE
index 5e0d7d52181ff3d6c21a7ceefee8e927b7d49476..214cfd682c0652a680bd4c1f498fafe690f9686b 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-07  Marek Polacek  <polacek@redhat.com>
+
+       PR c/64417
+       * gcc.c-torture/compile/pr28865.c: Add dg-errors.
+       * gcc.dg/pr64417.c: New test.
+
 2015-01-06  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR target/64505
index aa6ae078acaba257ac4e2644f480ec6496fff188..ef0eba5492d38467094bfceb5042d63f32018ec8 100644 (file)
@@ -5,12 +5,12 @@ struct var_len
 };
 
 /* Note - strictly speaking this array declaration is illegal
-   since each element has a variable length.  GCC allows it
-   (for the moment) because it is used in existing code, such
-   as glibc.  */
+   since each element has a variable length.  We used to allow
+   this because it was used in existing code.
+   Since PR64417 we reject this code.  */
 static const struct var_len var_array[] = 
 {
-  { 1, "Long exposure noise reduction" },
-  { 2, "Shutter/AE lock buttons" },
-  { 3, "Mirror lockup" }
+  { 1, "Long exposure noise reduction" }, /* { dg-error "initialization of flexible array member" } */
+  { 2, "Shutter/AE lock buttons" }, /* { dg-error "initialization of flexible array member" } */
+  { 3, "Mirror lockup" } /* { dg-error "initialization of flexible array member" } */
 };
diff --git a/gcc/testsuite/gcc.dg/pr64417.c b/gcc/testsuite/gcc.dg/pr64417.c
new file mode 100644 (file)
index 0000000..1e98b22
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR c/64417 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct foo { int x; char y[]; };
+struct bar { struct foo f; };
+struct baz { struct bar b; };
+
+struct foo a1 = { 1, "abc" };
+struct foo a2 = { 1, { "abc" } };
+struct foo b1[] = { { 1, "abc" } }; /* { dg-error "initialization of flexible array member" } */
+struct foo b2[] = { { 1, { "abc" } } }; /* { dg-error "initialization of flexible array member" } */
+struct bar c1[] = { { { 1, "abc" } } }; /* { dg-error "initialization of flexible array member" } */
+struct bar c2[] = { { { 1, { "abc" } } } }; /* { dg-error "initialization of flexible array member" } */
+struct baz d1[] = { { { { 1, "abc" } } } }; /* { dg-error "initialization of flexible array member" } */
+struct baz d2[] = { { { { 1, { "abc" } } } } }; /* { dg-error "initialization of flexible array member" } */