re PR c++/88261 (ICE: verify_gimple failed (error: non-trivial conversion at assignment))
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Mon, 7 Jan 2019 17:08:51 +0000 (17:08 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Mon, 7 Jan 2019 17:08:51 +0000 (17:08 +0000)
        PR c++/88261
        PR c++/69338
        PR c++/69696
        PR c++/69697
        * cp-tree.h (LOOKUP_ALLOW_FLEXARRAY_INIT): New flag value.
        * typeck2.c (digest_init_r): Raise an error for non-static
        initialization of a flexible array member.
        (process_init_constructor, massage_init_elt,
        process_init_constructor_array, process_init_constructor_record,
        process_init_constructor_union, process_init_constructor): Add the
        flags parameter and pass it thru.
        (store_init_value): Pass LOOKUP_ALLOW_FLEXARRAY_INIT parameter to
        digest_init_flags for static decls.

gcc/testsuite:
2019-01-07  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR c++/88261
        PR c++/69338
        PR c++/69696
        PR c++/69697
        * gcc.dg/array-6.c: Move from here ...
        * c-c++-common/array-6.c: ... to here and add some more test coverage.
        * g++.dg/pr69338.C: New test.
        * g++.dg/pr69697.C: Likewise.
        * g++.dg/ext/flexary32.C: Likewise.
        * g++.dg/ext/flexary3.C: Adjust test.
        * g++.dg/ext/flexary12.C: Likewise.
        * g++.dg/ext/flexary13.C: Likewise.
        * g++.dg/ext/flexary15.C: Likewise.
        * g++.dg/warn/Wplacement-new-size-1.C: Likewise.
        * g++.dg/warn/Wplacement-new-size-2.C: Likewise.
        * g++.dg/warn/Wplacement-new-size-6.C: Likewise.

From-SVN: r267653

16 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/array-6.c [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/flexary12.C
gcc/testsuite/g++.dg/ext/flexary13.C
gcc/testsuite/g++.dg/ext/flexary15.C
gcc/testsuite/g++.dg/ext/flexary3.C
gcc/testsuite/g++.dg/ext/flexary32.C [new file with mode: 0644]
gcc/testsuite/g++.dg/pr69338.C [new file with mode: 0644]
gcc/testsuite/g++.dg/pr69697.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C
gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C
gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C
gcc/testsuite/gcc.dg/array-6.c [deleted file]

index cbb70140c6999efd76cd1a32b4813c9f878fb8be..60c8ae1934eca33847f34dfe8f0e8c2560ff11ee 100644 (file)
@@ -1,3 +1,19 @@
+2019-01-07  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       PR c++/88261
+       PR c++/69338
+       PR c++/69696
+       PR c++/69697
+       * cp-tree.h (LOOKUP_ALLOW_FLEXARRAY_INIT): New flag value.
+       * typeck2.c (digest_init_r): Raise an error for non-static
+       initialization of a flexible array member.
+       (process_init_constructor, massage_init_elt,
+       process_init_constructor_array, process_init_constructor_record,
+       process_init_constructor_union, process_init_constructor): Add the
+       flags parameter and pass it thru.
+       (store_init_value): Pass LOOKUP_ALLOW_FLEXARRAY_INIT parameter to
+       digest_init_flags for static decls.
+
 2019-01-07  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/85052
index 794849b50662ccb2fa1dab19fc1f0eac28181e39..44739049b8d4e003cfb64f9f994527900b2aa417 100644 (file)
@@ -5454,6 +5454,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
 #define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND << 1)
 /* Used for delegating constructors in order to diagnose self-delegation.  */
 #define LOOKUP_DELEGATING_CONS (LOOKUP_NO_NON_INTEGRAL << 1)
+/* Allow initialization of a flexible array members.  */
+#define LOOKUP_ALLOW_FLEXARRAY_INIT (LOOKUP_DELEGATING_CONS << 1)
 
 #define LOOKUP_NAMESPACES_ONLY(F)  \
   (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
index 03b24a94edee2608e0da0a252b21ef37fd2d8def..ecc313b2355f0cef1ae0e55f20203a4dbad08e7a 100644 (file)
@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gcc-rich-location.h"
 
 static tree
-process_init_constructor (tree type, tree init, int nested,
+process_init_constructor (tree type, tree init, int nested, int flags,
                          tsubst_flags_t complain);
 
 
@@ -817,8 +817,12 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
   if (flags & LOOKUP_ALREADY_DIGESTED)
     value = init;
   else
-    /* Digest the specified initializer into an expression.  */
-    value = digest_init_flags (type, init, flags, tf_warning_or_error);
+    {
+      if (TREE_STATIC (decl))
+       flags |= LOOKUP_ALLOW_FLEXARRAY_INIT;
+      /* Digest the specified initializer into an expression.  */
+      value = digest_init_flags (type, init, flags, tf_warning_or_error);
+    }
 
   if (TREE_CODE (type) == ARRAY_TYPE
       && TYPE_STRING_FLAG (TREE_TYPE (type))
@@ -1068,8 +1072,18 @@ digest_init_r (tree type, tree init, int nested, int flags,
     {
       if (nested && !TYPE_DOMAIN (type))
        /* C++ flexible array members have a null domain.  */
-       pedwarn (loc, OPT_Wpedantic,
-                "initialization of a flexible array member");
+       {
+         if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT)
+           pedwarn (loc, OPT_Wpedantic,
+                    "initialization of a flexible array member");
+         else
+           {
+             if (complain & tf_error)
+               error_at (loc, "non-static initialization of"
+                              " a flexible array member");
+             return error_mark_node;
+           }
+       }
 
       tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
       if (char_type_p (typ1)
@@ -1193,7 +1207,8 @@ digest_init_r (tree type, tree init, int nested, int flags,
 
   if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
       && !TYPE_NON_AGGREGATE_CLASS (type))
-    return process_init_constructor (type, stripped_init, nested, complain);
+    return process_init_constructor (type, stripped_init, nested, flags,
+                                    complain);
   else
     {
       if (COMPOUND_LITERAL_P (stripped_init) && code == ARRAY_TYPE)
@@ -1291,9 +1306,12 @@ picflag_from_initializer (tree init)
 /* Adjust INIT for going into a CONSTRUCTOR.  */
 
 static tree
-massage_init_elt (tree type, tree init, int nested, tsubst_flags_t complain)
+massage_init_elt (tree type, tree init, int nested, int flags,
+                 tsubst_flags_t complain)
 {
-  init = digest_init_r (type, init, nested ? 2 : 1, LOOKUP_IMPLICIT, complain);
+  flags &= LOOKUP_ALLOW_FLEXARRAY_INIT;
+  flags |= LOOKUP_IMPLICIT;
+  init = digest_init_r (type, init, nested ? 2 : 1, flags, complain);
   /* Strip a simple TARGET_EXPR when we know this is an initializer.  */
   if (SIMPLE_TARGET_EXPR_P (init))
     init = TARGET_EXPR_INITIAL (init);
@@ -1311,11 +1329,11 @@ massage_init_elt (tree type, tree init, int nested, tsubst_flags_t complain)
    which describe the initializers.  */
 
 static int
-process_init_constructor_array (tree type, tree init, int nested,
+process_init_constructor_array (tree type, tree init, int nested, int flags,
                                tsubst_flags_t complain)
 {
   unsigned HOST_WIDE_INT i, len = 0;
-  int flags = 0;
+  int picflags = 0;
   bool unbounded = false;
   constructor_elt *ce;
   vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (init);
@@ -1365,7 +1383,8 @@ process_init_constructor_array (tree type, tree init, int nested,
        ce->index = error_mark_node;
       gcc_assert (ce->value);
       ce->value
-       = massage_init_elt (TREE_TYPE (type), ce->value, nested, complain);
+       = massage_init_elt (TREE_TYPE (type), ce->value, nested, flags,
+                           complain);
 
       gcc_checking_assert
        (ce->value == error_mark_node
@@ -1373,7 +1392,7 @@ process_init_constructor_array (tree type, tree init, int nested,
             (strip_array_types (TREE_TYPE (type)),
              strip_array_types (TREE_TYPE (ce->value)))));
 
-      flags |= picflag_from_initializer (ce->value);
+      picflags |= picflag_from_initializer (ce->value);
     }
 
   /* No more initializers. If the array is unbounded, we are done. Otherwise,
@@ -1389,7 +1408,8 @@ process_init_constructor_array (tree type, tree init, int nested,
               we can't rely on the back end to do it for us, so make the
               initialization explicit by list-initializing from T{}.  */
            next = build_constructor (init_list_type_node, NULL);
-           next = massage_init_elt (TREE_TYPE (type), next, nested, complain);
+           next = massage_init_elt (TREE_TYPE (type), next, nested, flags,
+                                    complain);
            if (initializer_zerop (next))
              /* The default zero-initialization is fine for us; don't
                 add anything to the CONSTRUCTOR.  */
@@ -1406,7 +1426,7 @@ process_init_constructor_array (tree type, tree init, int nested,
 
        if (next)
          {
-           flags |= picflag_from_initializer (next);
+           picflags |= picflag_from_initializer (next);
            if (len > i+1
                && (initializer_constant_valid_p (next, TREE_TYPE (next))
                    == null_pointer_node))
@@ -1426,7 +1446,7 @@ process_init_constructor_array (tree type, tree init, int nested,
       }
 
   CONSTRUCTOR_ELTS (init) = v;
-  return flags;
+  return picflags;
 }
 
 /* Subroutine of process_init_constructor, which will process an initializer
@@ -1434,7 +1454,7 @@ process_init_constructor_array (tree type, tree init, int nested,
    the initializers.  */
 
 static int
-process_init_constructor_record (tree type, tree init, int nested,
+process_init_constructor_record (tree type, tree init, int nested, int flags,
                                 tsubst_flags_t complain)
 {
   vec<constructor_elt, va_gc> *v = NULL;
@@ -1449,7 +1469,7 @@ process_init_constructor_record (tree type, tree init, int nested,
   gcc_assert (!TYPE_POLYMORPHIC_P (type));
 
  restart:
-  int flags = 0;
+  int picflags = 0;
   unsigned HOST_WIDE_INT idx = 0;
   int designator_skip = -1;
   /* Generally, we will always have an index for each initializer (which is
@@ -1517,7 +1537,7 @@ process_init_constructor_record (tree type, tree init, int nested,
          if (ce)
            {
              gcc_assert (ce->value);
-             next = massage_init_elt (type, next, nested, complain);
+             next = massage_init_elt (type, next, nested, flags, complain);
              ++idx;
            }
        }
@@ -1546,7 +1566,8 @@ process_init_constructor_record (tree type, tree init, int nested,
             for us, so build up TARGET_EXPRs.  If the type in question is
             a class, just build one up; if it's an array, recurse.  */
          next = build_constructor (init_list_type_node, NULL);
-         next = massage_init_elt (TREE_TYPE (field), next, nested, complain);
+         next = massage_init_elt (TREE_TYPE (field), next, nested, flags,
+                                  complain);
 
          /* Warn when some struct elements are implicitly initialized.  */
          if ((complain & tf_warning)
@@ -1597,7 +1618,7 @@ process_init_constructor_record (tree type, tree init, int nested,
       /* If this is a bitfield, now convert to the lowered type.  */
       if (type != TREE_TYPE (field))
        next = cp_convert_and_check (TREE_TYPE (field), next, complain);
-      flags |= picflag_from_initializer (next);
+      picflags |= picflag_from_initializer (next);
       CONSTRUCTOR_APPEND_ELT (v, field, next);
     }
 
@@ -1653,7 +1674,7 @@ process_init_constructor_record (tree type, tree init, int nested,
     }
 
   CONSTRUCTOR_ELTS (init) = v;
-  return flags;
+  return picflags;
 }
 
 /* Subroutine of process_init_constructor, which will process a single
@@ -1661,7 +1682,7 @@ process_init_constructor_record (tree type, tree init, int nested,
    which describe the initializer.  */
 
 static int
-process_init_constructor_union (tree type, tree init, int nested,
+process_init_constructor_union (tree type, tree init, int nested, int flags,
                                tsubst_flags_t complain)
 {
   constructor_elt *ce;
@@ -1749,7 +1770,7 @@ process_init_constructor_union (tree type, tree init, int nested,
 
   if (ce->value && ce->value != error_mark_node)
     ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested,
-                                 complain);
+                                 flags, complain);
 
   return picflag_from_initializer (ce->value);
 }
@@ -1769,40 +1790,43 @@ process_init_constructor_union (tree type, tree init, int nested,
    of error.  */
 
 static tree
-process_init_constructor (tree type, tree init, int nested,
+process_init_constructor (tree type, tree init, int nested, int flags,
                          tsubst_flags_t complain)
 {
-  int flags;
+  int picflags;
 
   gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
 
   if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type))
-    flags = process_init_constructor_array (type, init, nested, complain);
+    picflags = process_init_constructor_array (type, init, nested, flags,
+                                              complain);
   else if (TREE_CODE (type) == RECORD_TYPE)
-    flags = process_init_constructor_record (type, init, nested, complain);
+    picflags = process_init_constructor_record (type, init, nested, flags,
+                                               complain);
   else if (TREE_CODE (type) == UNION_TYPE)
-    flags = process_init_constructor_union (type, init, nested, complain);
+    picflags = process_init_constructor_union (type, init, nested, flags,
+                                              complain);
   else
     gcc_unreachable ();
 
-  if (flags & PICFLAG_ERRONEOUS)
+  if (picflags & PICFLAG_ERRONEOUS)
     return error_mark_node;
 
   TREE_TYPE (init) = type;
   if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
     cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
-  if (flags & PICFLAG_SIDE_EFFECTS)
+  if (picflags & PICFLAG_SIDE_EFFECTS)
     {
       TREE_CONSTANT (init) = false;
       TREE_SIDE_EFFECTS (init) = true;
     }
-  else if (flags & PICFLAG_NOT_ALL_CONSTANT)
+  else if (picflags & PICFLAG_NOT_ALL_CONSTANT)
     /* Make sure TREE_CONSTANT isn't set from build_constructor.  */
     TREE_CONSTANT (init) = false;
   else
     {
       TREE_CONSTANT (init) = 1;
-      if (!(flags & PICFLAG_NOT_ALL_SIMPLE))
+      if (!(picflags & PICFLAG_NOT_ALL_SIMPLE))
        TREE_STATIC (init) = 1;
     }
   return init;
index 13d8c065b1188541781193e532d68d9c5a7baa9a..4bb56349adff891e7d2358fb37ce46ef70cc52c6 100644 (file)
@@ -1,3 +1,22 @@
+2019-01-07  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       PR c++/88261
+       PR c++/69338
+       PR c++/69696
+       PR c++/69697
+       * gcc.dg/array-6.c: Move from here ...
+       * c-c++-common/array-6.c: ... to here and add some more test coverage.
+       * g++.dg/pr69338.C: New test.
+       * g++.dg/pr69697.C: Likewise.
+       * g++.dg/ext/flexary32.C: Likewise.
+       * g++.dg/ext/flexary3.C: Adjust test.
+       * g++.dg/ext/flexary12.C: Likewise.
+       * g++.dg/ext/flexary13.C: Likewise.
+       * g++.dg/ext/flexary15.C: Likewise.
+       * g++.dg/warn/Wplacement-new-size-1.C: Likewise.
+       * g++.dg/warn/Wplacement-new-size-2.C: Likewise.
+       * g++.dg/warn/Wplacement-new-size-6.C: Likewise.
+
 2019-01-07  Richard Earnshaw  <rearnsha@arm.com>
 
        * gcc.target/aarch64/subs_compare_2.c: Make '#' immediate prefix
diff --git a/gcc/testsuite/c-c++-common/array-6.c b/gcc/testsuite/c-c++-common/array-6.c
new file mode 100644 (file)
index 0000000..f3f2eda
--- /dev/null
@@ -0,0 +1,47 @@
+/* PR c/5597 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* Verify that GCC forbids non-static initialization of
+   flexible array members. */
+
+struct str { int len; char s[]; };
+
+struct str a = { 2, "a" };
+
+void foo()
+{
+  static struct str b = { 2, "b" };
+  struct str c = { 2, "c" }; /* { dg-error "(non-static)|(near initialization)" } */
+  struct str d = (struct str) { 2, "d" }; /* { dg-error "(non-static)|(near initialization)" } */
+  struct str e = (struct str) { d.len, "e" }; /* { dg-error "(non-static)|(initialization)" } */
+}
+
+struct str f = { 0, {} };
+
+void bar()
+{
+  static struct str g = { 0, {} };
+  struct str h = { 0, {} }; /* { dg-error "(non-static)|(near initialization)" } */
+  struct str i = (struct str) { 0, {} }; /* { dg-error "(non-static)|(near initialization)" } */
+  struct str j = (struct str) { i.len, {} }; /* { dg-error "(non-static)|(initialization)" } */
+}
+
+struct str k = { 0 };
+
+void baz()
+{
+  static struct str l = { 0 };
+  struct str m = { 0 };
+  struct str n = (struct str) { 0 };
+  struct str o = (struct str) { n.len };
+}
+
+struct str p = {};
+
+void qux()
+{
+  static struct str q = {};
+  struct str r = {};
+  struct str s = (struct str) {};
+}
index 61726f63f2846ac0383ca74fe8717656193b1292..b0964948731d8172fab1e27f655ab908ba750c1e 100644 (file)
@@ -12,7 +12,7 @@ struct A {
 void f1 ()
 {
   // This is the meat of the test from c++/69290:
-  struct A a
+  static struct A a
     = { "c" };   // { dg-error "invalid conversion from .const char\\*. to .int." }
 
   (void)&a;
@@ -27,13 +27,13 @@ struct B {
 
 void f2 ()
 {
-  struct B b1
+  static struct B b1
     = { 0, "c" };   // { dg-error "invalid conversion from .const char\\*. to .int." }
 
   (void)&b1;
 
   const char s[] = "c";
-  struct B b2
+  static struct B b2
     = { 0, s };   // { dg-error "invalid conversion from .const char\\*. to .int." }
 
   (void)&b2;
@@ -57,7 +57,7 @@ struct C {
 
 void f3 ()
 {
-  struct C<double> cd
+  static struct C<double> cd
     = { "c" };   // { dg-error "cannot convert .const char\\*. to .double." }
 
   (void)&cd;
index f1f4e22a3ffaeab76077947447c67256596b6126..7c67d09ee5a7cedc37ea5b4ff04f8e44ba82af8a 100644 (file)
@@ -19,33 +19,33 @@ int main ()
     ASSERT (s.n == 0);
   }
   {
-    Ax s =
+    static Ax s =
       { 0, { } };   // dg-warning "initialization of a flexible array member" }
     ASSERT (s.n == 0);
   }
   {
-    Ax s =
+    static Ax s =
       { 1, { 2 } };   // dg-warning "initialization of a flexible array member" }
     ASSERT (s.n == 1 && s.a [0] == 2);
   }
   {
-    Ax s =
+    static Ax s =
       { 2, { 3, 4 } }; // dg-warning "initialization of a flexible array member" }
     ASSERT (s.n = 2 && s.a [0] == 3 && s.a [1] == 4);
   }
   {
-    Ax s =
+    static Ax s =
       { 123, i };   // dg-warning "initialization of a flexible array member" }
     ASSERT (s.n == 123 && s.a [0] == i);
   }
   {
-    Ax s =
+    static Ax s =
       { 456, { i } }; // dg-warning "initialization of a flexible array member" }
     ASSERT (s.n == 456 && s.a [0] == i);
   }
   {
     int j = i + 1, k = j + 1;
-    Ax s =
+    static Ax s =
       { 3, { i, j, k } }; // dg-warning "initialization of a flexible array member" }
     ASSERT (s.n == 3 && s.a [0] == i && s.a [1] == j && s.a [2] == k);
   }
index c03a60e7b50a6b5af1a0465dad80927f229a0a05..da5f5f43123eca995eac464eb9c749df0f7e74ff 100644 (file)
@@ -10,5 +10,5 @@ struct S {
 
 void foo (const char *a)
 {
-  const S s = { 1, { a, "b" } };   // { dg-warning "invalid conversion" }
+  static const S s = { 1, { a, "b" } };   // { dg-warning "invalid conversion" }
 }
index c7c0e79335546498891f58ceb89d6b56a1debc00..34b17254f8cd381ec0c90025ab2e830b7f6ff7c3 100644 (file)
@@ -17,5 +17,6 @@ struct s {
 int main()
 {
     struct s s = { .c = 0 };   // { dg-error "initializer" }
+    // { dg-error "non-static initialization of a flexible array member" "" { target *-*-* } .-1 }
     return 0;
 }
diff --git a/gcc/testsuite/g++.dg/ext/flexary32.C b/gcc/testsuite/g++.dg/ext/flexary32.C
new file mode 100644 (file)
index 0000000..7ca78b1
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-options -Wno-pedantic } */
+
+struct str { int len; char s[]; };
+
+struct foo {
+  str x = {3, {1,2,3}}; /* { dg-error "(non-static)|(initialization)" } */
+  foo() {}
+};
+
+struct bar {
+  static constexpr str x = {3, {1,2,3}};
+  bar() {}
+};
+
+struct baz {
+  str x = {3};
+  baz() {}
+};
diff --git a/gcc/testsuite/g++.dg/pr69338.C b/gcc/testsuite/g++.dg/pr69338.C
new file mode 100644 (file)
index 0000000..8b1351b
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-additional-options "-Wno-pedantic" } */
+
+struct A { char i, a[]; };
+
+void foo()
+{
+  struct A a0 = { 3, "AB" };                /* { dg-error "(non-static)|(initialization)" } */
+}
+
+struct A a1 = { 3, "AB" };                  /* { dg-bogus "(non-static)|(initialization)" } */
+
+struct A a2 = (struct A){ 3, "AB" };        /* { dg-error "(non-static)|(initialization)" } */
+
+struct B1 {
+    A a3;
+    B1 (): a3 { 3, "AB" } { }               /* { dg-error "(non-static)|(initialization)" } */
+} b1;
+
+struct B2 {
+    A a4;
+    B2 (): a4 ((struct A){ 3, "AB" }) { }   /* { dg-error "(non-static)|(initialization)" } */
+} b2;
diff --git a/gcc/testsuite/g++.dg/pr69697.C b/gcc/testsuite/g++.dg/pr69697.C
new file mode 100644 (file)
index 0000000..b0b7236
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-additional-options "-Wno-pedantic" } */
+
+int i;
+struct A { int n, a[]; }
+  a = i ? A({ 1, { 2 } })     /* { dg-error "(non-static)|(initialization)" } */
+        : A({ 2, { 3, 4 } }); /* { dg-error "(non-static)|(initialization)" } */
index 716986d46645dffe2b01869787b6e4cf0e482611..d2ec608afd4cee767d88513bd24b95f75701d109 100644 (file)
@@ -28,7 +28,7 @@ void fAx (Ax *px, Ax &rx)
 
 void fAx2 ()
 {
-  Ax ax2 = { 1, { 2, 3 } };
+  static Ax ax2 = { 1, { 2, 3 } };
 
   new (ax2.a) Int16;
   new (ax2.a) Int32;    // { dg-warning "placement" }
@@ -82,7 +82,7 @@ void fBx (BAx *pbx, BAx &rbx)
 
 void fBx1 ()
 {
-  BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } };
+  static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } };
 
   new (bax1.ax.a) char;            // { dg-warning "placement" }
   new (bax1.ax.a) char[2];  // { dg-warning "placement" }
index 3d470747e24315c12c921c0c0c605ee5ae0e5df9..e00515eeaa959cc3f7891f1ac64a87769fc4c0f5 100644 (file)
@@ -33,13 +33,13 @@ void fAx (Ax *px, Ax &rx)
 void fAx2 ()
 {
   // Initialization of non-static objects with flexible array members
-  // isn't allowed in C and should perhaps be disallowed in C++ as
+  // isn't allowed in C and had to be be disallowed in C++ as
   // well to avoid c++/69696 - incorrect initialization of block-scope
   // flexible array members.
-  Ax ax2 = { 1, { 2, 3 } };
+  Ax ax2 = { 1, { 2, 3 } };   // { dg-error "non-static initialization of a flexible array member" }
 
-  new (ax2.a) Int16;
-  new (ax2.a) Int16[1];
+  new (ax2.a) Int16;          // { dg-warning "placement" }
+  new (ax2.a) Int16[1];       // { dg-warning "placement" }
   new (ax2.a) Int16[2];       // { dg-warning "placement" }
   new (ax2.a) Int32;          // { dg-warning "placement" }
   new (ax2.a) Int32[2];       // { dg-warning "placement" }
@@ -140,7 +140,7 @@ void fBx (BAx *pbx, BAx &rbx)
 
 void fBx1 ()
 {
-  BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } };
+  static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } };
 
   new (bax1.ax.a) char;              // { dg-warning "placement" }
   new (bax1.ax.a) char[2];    // { dg-warning "placement" }
index 06dfb3a0ba0b4d80486539a1c5518f284597ae24..b6a72b18f6a26f43085e0c42dd99517fef0fc724 100644 (file)
@@ -15,7 +15,7 @@ struct BAx { int i; Ax ax; };
 
 void fBx1 ()
 {
-  BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } };       // { dg-error "initialization of flexible array member in a nested context" }
+  static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } }; // { dg-error "initialization of flexible array member in a nested context" }
 
   new (bax1.ax.a) char;     // { dg-warning "placement" }
   new (bax1.ax.a) char[2];  // { dg-warning "placement" }
@@ -25,7 +25,7 @@ void fBx1 ()
 
 void fBx2 ()
 {
-  BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } };    // { dg-error "initialization of flexible array member in a nested context" }
+  static BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } }; // { dg-error "initialization of flexible array member in a nested context" }
 
   new (bax2.ax.a) char;       // { dg-warning "placement" }
   new (bax2.ax.a) char[2];    // { dg-warning "placement" }
@@ -37,7 +37,7 @@ void fBx2 ()
 
 void fBx3 ()
 {
-  BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } }; // { dg-error "initialization of flexible array member in a nested context" }
+  static BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } }; // { dg-error "initialization of flexible array member in a nested context" }
 
   new (bax2.ax.a) char;       // { dg-warning "placement" }
   new (bax2.ax.a) char[2];    // { dg-warning "placement" }
diff --git a/gcc/testsuite/gcc.dg/array-6.c b/gcc/testsuite/gcc.dg/array-6.c
deleted file mode 100644 (file)
index 6ef6462..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* PR c/5597 */
-/* { dg-do compile } */
-/* { dg-options "" } */
-
-/* Verify that GCC forbids non-static initialization of
-   flexible array members. */
-
-struct str { int len; char s[]; };
-
-struct str a = { 2, "a" };
-
-void foo()
-{
-  static struct str b = { 2, "b" };
-  struct str c = { 2, "c" }; /* { dg-error "(non-static)|(near initialization)" } */
-  struct str d = (struct str) { 2, "d" }; /* { dg-error "(non-static)|(near initialization)" } */
-  struct str e = (struct str) { d.len, "e" }; /* { dg-error "(non-static)|(initialization)" } */
-}