]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible array
authorMartin Sebor <msebor@gcc.gnu.org>
Thu, 4 Feb 2016 04:50:42 +0000 (21:50 -0700)
committerMartin Sebor <msebor@gcc.gnu.org>
Thu, 4 Feb 2016 04:50:42 +0000 (21:50 -0700)
PR c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible array
               member
PR c++/69253 - [6 Regression] ICE in cxx_incomplete_type_diagnostic initializing
               a flexible array member with empty string
PR c++/69290 - [6 Regression] ICE on invalid initialization of a flexible array
               member
PR c++/69277 - [6 Regression] ICE mangling a flexible array member
PR c++/69349 - template substitution error for flexible array members

gcc/testsuite/ChangeLog:
2016-02-03  Martin Sebor  <msebor@redhat.com>

PR c++/69251
PR c++/69253
PR c++/69290
PR c++/69277
PR c++/69349
* g++.dg/ext/flexarray-mangle-2.C: New test.
* g++.dg/ext/flexarray-mangle.C: New test.
* g++.dg/ext/flexarray-subst.C: New test.
* g++.dg/ext/flexary11.C: New test.
* g++.dg/ext/flexary12.C: New test.
* g++.dg/ext/flexary13.C: New test.
* g++.dg/ext/flexary14.C: New test.
* g++.dg/other/dump-ada-spec-2.C: Adjust.

gcc/cp/ChangeLog:
2016-02-03  Martain Sebor  <msebor@redhat.com>

PR c++/69251
PR c++/69253
PR c++/69290
PR c++/69277
PR c++/69349
* class.c (walk_subobject_offsets): Avoid testing the upper bound
of a flexible array member for equality to null.
(find_flexarrays): Remove spurious whitespace introduced in r231665.
(diagnose_flexarrays): Avoid checking the upper bound of arrays.
(check_flexarrays): Same.
* decl.c (compute_array_index_type): Avoid special case for flexible
array members.
(grokdeclarator): Avoid calling compute_array_index_type for flexible
array members.
* error.c (dump_type_suffix): Revert changes introduced in r231665
and rendered unnecessary by the changes above.
* pt.c (tsubst):  Same.
* tree.c (build_ctor_subob_ref): Handle flexible array members.
* typeck2.c (digest_init_r): Revert changes introduced in r231665.
(process_init_constructor_array): Same.
(process_init_constructor_record): Same.

From-SVN: r233126

17 files changed:
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/mangle.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/flexarray-mangle.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/flexarray-subst.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/flexary11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/flexary12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/flexary13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/flexary14.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/dump-ada-spec-2.C

index 6ac9a648271634e14f7266452d8671d169d53479..c8ccf405d841117d833405213ed86840cb19ccf4 100644 (file)
@@ -1,3 +1,27 @@
+2016-02-02  Martain Sebor  <msebor@redhat.com>
+
+       PR c++/69251
+       PR c++/69253
+       PR c++/69290
+       PR c++/69277
+       PR c++/69349
+       * class.c (walk_subobject_offsets): Avoid testing the upper bound
+       of a flexible array member for equality to null.
+       (find_flexarrays): Remove spurious whitespace introduced in r231665.
+       (diagnose_flexarrays): Avoid checking the upper bound of arrays.
+       (check_flexarrays): Same.
+       * decl.c (compute_array_index_type): Avoid special case for flexible
+       array members.
+       (grokdeclarator): Avoid calling compute_array_index_type for flexible
+       array members.
+       * error.c (dump_type_suffix): Revert changes introduced in r231665
+       and rendered unnecessary by the changes above.
+       * pt.c (tsubst):  Same.
+       * tree.c (build_ctor_subob_ref): Handle flexible array members.
+       * typeck2.c (digest_init_r): Revert changes introduced in r231665.
+       (process_init_constructor_array): Same.
+       (process_init_constructor_record): Same.
+
 2016-02-03  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c++/69056
index 45d8a2432459b728bf74bade9d457241ca73eb53..67b3f81de25729f7edc7bf007032a94d816433dc 100644 (file)
@@ -4120,9 +4120,7 @@ walk_subobject_offsets (tree type,
       /* Avoid recursing into objects that are not interesting.  */
       if (!CLASS_TYPE_P (element_type)
          || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)
-         || !domain
-         /* Flexible array members have no upper bound.  */
-         || !TYPE_MAX_VALUE (domain))
+         || !domain)
        return 0;
 
       /* Step through each of the elements in the array.  */
@@ -6645,7 +6643,7 @@ find_flexarrays (tree t, flexmems_t *fmem)
       for (next = fld;
           (next = DECL_CHAIN (next))
             && TREE_CODE (next) != FIELD_DECL; );
-      
+
       tree fldtype = TREE_TYPE (fld);
       if (TREE_CODE (fld) != TYPE_DECL
          && RECORD_OR_UNION_TYPE_P (fldtype)
@@ -6672,22 +6670,20 @@ find_flexarrays (tree t, flexmems_t *fmem)
          /* Remember the first non-static data member.  */
          if (!fmem->first)
            fmem->first = fld;
-         
+
          /* Remember the first non-static data member after the flexible
             array member, if one has been found, or the zero-length array
             if it has been found.  */
          if (!fmem->after && fmem->array)
            fmem->after = fld;
        }
-           
+
       /* Skip non-arrays.  */
       if (TREE_CODE (fldtype) != ARRAY_TYPE)
        continue;
 
       /* Determine the upper bound of the array if it has one.  */
-      tree dom = TYPE_DOMAIN (fldtype);
-
-      if (dom && TYPE_MAX_VALUE (dom))
+      if (tree dom = TYPE_DOMAIN (fldtype))
        {
          if (fmem->array)
            {
@@ -6710,14 +6706,13 @@ find_flexarrays (tree t, flexmems_t *fmem)
            {
              /* Replace the zero-length array if it's been stored and
                 reset the after pointer.  */
-             dom = TYPE_DOMAIN (TREE_TYPE (fmem->array));
-             if (dom && TYPE_MAX_VALUE (dom))
+             if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
                {
                  fmem->array = fld;
                  fmem->after = NULL_TREE;
                }
            }
-         else  
+         else
            fmem->array = fld;
        }
     }
@@ -6737,8 +6732,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
 
   const char *msg = 0;
 
-  const_tree dom = TYPE_DOMAIN (TREE_TYPE (fmem->array));
-  if (dom && TYPE_MAX_VALUE (dom))
+  if (const_tree dom = TYPE_DOMAIN (TREE_TYPE (fmem->array)))
     {
       if (fmem->after)
        msg = G_("zero-size array member %qD not at end of %q#T");
@@ -6770,7 +6764,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
              inform (DECL_SOURCE_LOCATION (fmem->after),
                      "next member %q#D declared here",
                      fmem->after);
-         
+
          inform (location_of (t), "in the definition of %q#T", t);
        }
     }
@@ -6844,7 +6838,7 @@ check_flexarrays (tree t, flexmems_t *fmem /* = NULL */)
   find_flexarrays (t, fmem);
 
   if (fmem == &flexmems)
-    { 
+    {
       /* Issue diagnostics for invalid flexible and zero-length array members
         found in base classes or among the members of the current class.  */
       diagnose_flexarrays (t, fmem);
index 8da87d325b00e3e52583df710497e2e41cda0d18..2c337bc3d188cdae6f99dfe9fe2bf5718f6a02d8 100644 (file)
@@ -8645,10 +8645,9 @@ fold_sizeof_expr (tree t)
   return r;
 }
 
-/* Given the SIZE (i.e., number of elements) in an array, compute an
-   appropriate index type for the array.  When SIZE is null, the array
-   is a flexible array member.  If non-NULL, NAME is the name of
-   the entity being declared.  */
+/* Given the SIZE (i.e., number of elements) in an array, compute
+   an appropriate index type for the array.  If non-NULL, NAME is
+   the name of the entity being declared.  */
 
 tree
 compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
@@ -8656,9 +8655,6 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
   tree itype;
   tree osize = size;
 
-  if (size == NULL_TREE)
-    return build_index_type (NULL_TREE);
-
   if (error_operand_p (size))
     return error_mark_node;
 
@@ -10967,11 +10963,10 @@ grokdeclarator (const cp_declarator *declarator,
                error ("flexible array member in union");
                type = error_mark_node;
              }
-           else
+           else 
              {
-               tree itype = compute_array_index_type (dname, NULL_TREE,
-                                                      tf_warning_or_error);
-               type = build_cplus_array_type (TREE_TYPE (type), itype);
+               /* Flexible array member has a null domain.  */
+               type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
              }
          }
 
index 89a00a02a3aa4a1e4d4f6151a81a5efafe4bd0fb..3f9cf4a793f93dfaf4663a72a0d840c3a3ff057b 100644 (file)
@@ -875,10 +875,10 @@ dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
     case ARRAY_TYPE:
       pp_maybe_space (pp);
       pp_cxx_left_bracket (pp);
-      if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t)))
+      if (tree dtype = TYPE_DOMAIN (t))
        {
-         tree dtype = TYPE_DOMAIN (t);
          tree max = TYPE_MAX_VALUE (dtype);
+         /* Zero-length arrays have an upper bound of SIZE_MAX.  */
          if (integer_all_onesp (max))
            pp_character (pp, '0');
          else if (tree_fits_shwi_p (max))
index 2bb70481d1f15b8fe78e3732811ab79757cd7481..410c7f46dcab45d1bff1954350ac9afdb483170a 100644 (file)
@@ -3280,8 +3280,10 @@ write_template_template_arg (const tree decl)
                  ::= A <expression> _ </element/ type>
 
      "Array types encode the dimension (number of elements) and the
-     element type. For variable length arrays, the dimension (but not
-     the '_' separator) is omitted."  */
+     element type.  For variable length arrays, the dimension (but not
+     the '_' separator) is omitted."
+     Note that for flexible array members, like for other arrays of
+     unspecified size, the dimension is also omitted.  */
 
 static void
 write_array_type (const tree type)
@@ -3290,29 +3292,31 @@ write_array_type (const tree type)
   if (TYPE_DOMAIN (type))
     {
       tree index_type;
-      tree max;
 
       index_type = TYPE_DOMAIN (type);
-      /* The INDEX_TYPE gives the upper and lower bounds of the
-        array.  */
-      max = TYPE_MAX_VALUE (index_type);
-      if (TREE_CODE (max) == INTEGER_CST)
+      /* The INDEX_TYPE gives the upper and lower bounds of the array.
+        It's null for flexible array members which have no upper bound
+        (this is a change from GCC 5 and prior where such members were
+        incorrectly mangled as zero-length arrays).  */
+      if (tree max = TYPE_MAX_VALUE (index_type))
        {
-         /* The ABI specifies that we should mangle the number of
-            elements in the array, not the largest allowed index.  */
-         offset_int wmax = wi::to_offset (max) + 1;
-         /* Truncate the result - this will mangle [0, SIZE_INT_MAX]
-            number of elements as zero.  */
-         wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max)));
-         gcc_assert (wi::fits_uhwi_p (wmax));
-         write_unsigned_number (wmax.to_uhwi ());
-       }
-      else
-       {
-         max = TREE_OPERAND (max, 0);
-         write_expression (max);
+         if (TREE_CODE (max) == INTEGER_CST)
+           {
+             /* The ABI specifies that we should mangle the number of
+                elements in the array, not the largest allowed index.  */
+             offset_int wmax = wi::to_offset (max) + 1;
+             /* Truncate the result - this will mangle [0, SIZE_INT_MAX]
+                number of elements as zero.  */
+             wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max)));
+             gcc_assert (wi::fits_uhwi_p (wmax));
+             write_unsigned_number (wmax.to_uhwi ());
+           }
+         else
+           {
+             max = TREE_OPERAND (max, 0);
+             write_expression (max);
+           }
        }
-
     }
   write_char ('_');
   write_type (TREE_TYPE (type));
index 9cde9c738f6f0e2334e175a2a9875e25c2a36683..e7ce74c6c05239dabb55067488a353262e7ea4f1 100644 (file)
@@ -12846,14 +12846,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       if (t == integer_type_node)
        return t;
 
-      if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST)
-        {
-          if (!TYPE_MAX_VALUE (t))
-            return compute_array_index_type (NULL_TREE, NULL_TREE, complain);
-          
-          if (TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
-            return t;
-        }
+      if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST
+          && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
+        return t;
 
       {
        tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
index 2bf37bcabc1689d52a43dca54a6eba7fe192f1ce..3203acaff9e94f6d6c23a4f8390b82764ef5158e 100644 (file)
@@ -2586,8 +2586,19 @@ build_ctor_subob_ref (tree index, tree type, tree obj)
     obj = build_class_member_access_expr (obj, index, NULL_TREE,
                                          /*reference*/false, tf_none);
   if (obj)
-    gcc_assert (same_type_ignoring_top_level_qualifiers_p (type,
-                                                          TREE_TYPE (obj)));
+    {
+      tree objtype = TREE_TYPE (obj);
+      if (TREE_CODE (objtype) == ARRAY_TYPE && !TYPE_DOMAIN (objtype))
+       {
+         /* When the destination object refers to a flexible array member
+            verify that it matches the type of the source object except
+            for its domain.  */
+         gcc_assert (comptypes (type, objtype, COMPARE_REDECLARATION));
+       }
+      else
+       gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, objtype));
+    }
+
   return obj;
 }
 
index ac2f3c366e8d1292da303b0eb87da330c4dcf9fc..419faa2655e55960a484537723bb40ae2aa4f423 100644 (file)
@@ -1015,14 +1015,13 @@ digest_init_r (tree type, tree init, bool nested, int flags,
      them if they were present.  */
   if (code == ARRAY_TYPE)
     {
-      if (nested
-         && (!TYPE_DOMAIN (type) || !TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
+      if (nested && !TYPE_DOMAIN (type))
        {
-         /* Flexible array members do not have an upper bound.  */
+         /* C++ flexible array members have a null domain.  */
          pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wpedantic,
                   "initialization of a flexible array member");
        }
-      
+
       tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
       if (char_type_p (typ1)
          /*&& init */
@@ -1061,9 +1060,7 @@ digest_init_r (tree type, tree init, bool nested, int flags,
              init = copy_node (init);
              TREE_TYPE (init) = type;
            }
-         if (TYPE_DOMAIN (type)
-             && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
-             && TREE_CONSTANT (TYPE_SIZE (type)))
+         if (TYPE_DOMAIN (type) && TREE_CONSTANT (TYPE_SIZE (type)))
            {
              /* Not a flexible array member.  */
              int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
@@ -1252,12 +1249,11 @@ process_init_constructor_array (tree type, tree init,
 
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
+      /* C++ flexible array members have a null domain.  */
       tree domain = TYPE_DOMAIN (type);
-      /* Flexible array members have no upper bound.  */
-      tree maxval = domain ? TYPE_MAX_VALUE (domain) : NULL_TREE;
-      if (domain && maxval && TREE_CONSTANT (maxval))
-       len = wi::ext (wi::to_offset (maxval)
-                      - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1,
+      if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
+       len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain))
+                       - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1,
                       TYPE_PRECISION (TREE_TYPE (domain)),
                       TYPE_SIGN (TREE_TYPE (domain))).to_uhwi ();
       else
@@ -1451,9 +1447,7 @@ process_init_constructor_record (tree type, tree init,
          /* Warn when some struct elements are implicitly initialized
             to zero.  However, avoid issuing the warning for flexible
             array members since they need not have any elements.  */
-         if ((TREE_CODE (fldtype) != ARRAY_TYPE
-              || (TYPE_DOMAIN (fldtype)
-                  && TYPE_MAX_VALUE (TYPE_DOMAIN (fldtype))))
+         if ((TREE_CODE (fldtype) != ARRAY_TYPE || TYPE_DOMAIN (fldtype))
              && (complain & tf_warning)
              && !EMPTY_CONSTRUCTOR_P (init))
            warning (OPT_Wmissing_field_initializers,
index 9eea63b8f8f7db004daa5296f41298dee5ae5fef..b050772ece8fcfa98f833c0124355f07f87c14f2 100644 (file)
@@ -1,3 +1,19 @@
+2016-02-03  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/69251
+       PR c++/69253
+       PR c++/69290
+       PR c++/69277
+       PR c++/69349
+       * g++.dg/ext/flexarray-mangle-2.C: New test.
+       * g++.dg/ext/flexarray-mangle.C: New test.
+       * g++.dg/ext/flexarray-subst.C: New test.
+       * g++.dg/ext/flexary11.C: New test.
+       * g++.dg/ext/flexary12.C: New test.
+       * g++.dg/ext/flexary13.C: New test.
+       * g++.dg/ext/flexary14.C: New test.
+       * g++.dg/other/dump-ada-spec-2.C: Adjust.
+
 2016-02-03  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gcc.target/i386/iamcu/test_passing_unions.c (check_union_passing6):
diff --git a/gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C b/gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C
new file mode 100644 (file)
index 0000000..98bd5f5
--- /dev/null
@@ -0,0 +1,46 @@
+// PR c++/69277 - [6 Regression] ICE mangling a flexible array member
+// { dg-do compile { target c++11 } }
+
+struct A {
+  int n;
+  char a [];
+};
+
+// Declare but do not define function templates.
+template <class T>
+void foo ();
+
+template <typename T>
+void fooref (T&);
+
+// Rvalue references are a C++ 11 feature.
+template <typename T>
+void foorefref (T&&);
+
+void bar (A a)
+{
+  // Decltype is also a C++ 11 feature.
+  // Verify that decltype gets the right type and that foo is
+  // mangled correctly.
+  foo<decltype (a.a)>();
+
+  // Verify that function templates taking a reference and an rvalue
+  // references (as in PR c++/69277) are also mangled correctly.
+  fooref (a.a);
+  foorefref (a.a);
+}
+
+// In G++ versions prior to 6, flexible array members were incorrectly
+// mangled as arrays of zero elements.  Verify that flexible array
+// members are mangled correctly as arrays of an unspecified number
+// of elements.
+
+// void foo<char []>():
+// { dg-final { scan-assembler _Z3fooIA_cEvv } }
+
+// The following is derived from PR c++/69277:
+// void fooref<char []>(char (&) [])
+// { dg-final { scan-assembler _Z6foorefIA_cEvRT_ } }
+
+// void foorefref<char (&) []>(char (&) [])
+// { dg-final { scan-assembler _Z9foorefrefIRA_cEvOT_ } }
diff --git a/gcc/testsuite/g++.dg/ext/flexarray-mangle.C b/gcc/testsuite/g++.dg/ext/flexarray-mangle.C
new file mode 100644 (file)
index 0000000..d8a8c0a
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/69277 - [6 Regression] ICE mangling a flexible array member
+// { dg-do compile }
+
+struct A {
+  int n;
+  char a [];
+};
+
+// Declare but do not define function templates.
+template <typename T>
+void fooref (T&);
+
+void bar (A a)
+{
+  fooref (a.a);
+}
+
+// In G++ versions prior to 6, flexible array members were incorrectly
+// mangled as arrays of zero elements.  Verify that flexible array
+// members are mangled correctly as arrays of an unspecified number
+// of elements.
+
+// void fooref<char []>(char (&) [])
+// { dg-final { scan-assembler _Z6foorefIA_cEvRT_ } }
diff --git a/gcc/testsuite/g++.dg/ext/flexarray-subst.C b/gcc/testsuite/g++.dg/ext/flexarray-subst.C
new file mode 100644 (file)
index 0000000..f644636
--- /dev/null
@@ -0,0 +1,33 @@
+// PR c++/69251 - [6 Regression] ICE (segmentation fault) in unify_array_domain
+// on i686-linux-gnu
+// { dg-do compile }
+
+struct A { int n; char a[]; };
+
+template <class>
+struct B;
+
+// The following definition shouldn't be needed but is provided to prevent
+// the test from failing with an error due to PR c++/69349 - template
+// substitution error for flexible array members.  (This doesn't compromise
+// the validity of this test since all it tests for is the absennce of
+// the ICE.)
+template <class>
+struct B { typedef int X; };
+
+template <class T>
+struct B<T[]> { typedef int X; };
+
+template <class T>
+struct C { typedef typename B<T>::X X; };
+
+template <class T>
+int foo (T&, typename C<T>::X = 0)
+{
+  return 0;
+}
+
+void bar (A *a)
+{
+  foo (a->a);
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary11.C b/gcc/testsuite/g++.dg/ext/flexary11.C
new file mode 100644 (file)
index 0000000..5bf774f
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/69253 - [6 Regression] g++ ICE at -O0 on x86_64-linux-gnu
+//                in "cxx_incomplete_type_diagnostic"
+// { dg-do compile }
+
+struct A {
+  int n;
+  char a [];
+};
+
+void f ()
+{
+  // Compound literals and flexible array members are G++ extensions
+  // accepted for compatibility with C and GCC.
+
+  // The following use of a flexible array member in a compound literal
+  // is invalid in C and rejected by GCC in C mode and so it's also
+  // rejected in C++ mode.
+  (struct A){ 1, "" };   // { dg-error "forbids compound-literals|initialization of a flexible array member|invalid use of a flexible array member" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary12.C b/gcc/testsuite/g++.dg/ext/flexary12.C
new file mode 100644 (file)
index 0000000..3d8c805
--- /dev/null
@@ -0,0 +1,63 @@
+// PR c++/69290 - [6 Regression] g++ ICE on invalid initialization
+//     of a flexible array member
+// { dg-do compile }
+
+// Suppress pedantic errors about initialization of a flexible array member.
+// { dg-options "-Wno-pedantic" }
+
+struct A {
+  int a [];  // { dg-error "flexible array member .A::a. in an otherwise empty .struct A." }
+};
+
+void f1 ()
+{
+  // This is the meat of the test from c++/69290:
+  struct A a
+    = { "c" };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&a;
+}
+
+
+// Exercise other forms of invalid initialization besides the one in the bug.
+struct B {
+  int n;
+  int a [];
+};
+
+void f2 ()
+{
+  struct B b1
+    = { 0, "c" };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&b1;
+
+  const char s[] = "c";
+  struct B b2
+    = { 0, s };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&b2;
+}
+
+struct D {
+  int a [];  // { dg-error "flexible array member .D::a. in an otherwise empty .struct D." }
+  D ();
+};
+
+D::D ():
+  a ("c")   // { dg-error "incompatible types in assignment of .const char \\\[2\\\]. to .int \\\[\\\]." }
+{ }
+
+
+template <class T>
+struct C {
+  T a [];  // { dg-error "flexible array member" }
+};
+
+void f3 ()
+{
+  struct C<double> cd
+    = { "c" };   // { dg-error "cannot convert .const char\\*. to .double." }
+
+  (void)&cd;
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary13.C b/gcc/testsuite/g++.dg/ext/flexary13.C
new file mode 100644 (file)
index 0000000..462ed65
--- /dev/null
@@ -0,0 +1,64 @@
+// { dg-do compile }
+// { dg-options -Wno-pedantic }
+
+#define STR(s) #s
+#define ASSERT(exp) \
+  ((exp) ? (void)0 : (void)(__builtin_printf ("%s:%i: assertion %s failed\n", \
+                     __FILE__, __LINE__, STR(exp)), \
+                      __builtin_abort ()))
+
+struct Ax { int n, a[]; };
+struct AAx { int i; Ax ax; };
+
+int i = 12345678;
+
+int main ()
+{
+  {
+    Ax s = { 0 };
+    ASSERT (s.n == 0);
+  }
+  {
+    Ax s =
+      { 0, { } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 0);
+  }
+  {
+    Ax s =
+      { 1, { 2 } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 1 && s.a [0] == 2);
+  }
+  {
+    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 =
+      { 123, i };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 123 && s.a [0] == i);
+  }
+  {
+    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 =
+      { 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);
+  }
+
+  {
+    AAx s =
+      { 1, { 2 } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.i == 1 && s.ax.n == 2);
+  }
+
+  {
+    AAx s =
+      { 1, { 2, { 3 } } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.i == 1 && s.ax.n == 2 && s.ax.a [0] == 3);
+  }
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary14.C b/gcc/testsuite/g++.dg/ext/flexary14.C
new file mode 100644 (file)
index 0000000..7365357
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/69349 - template substitution error for flexible array members
+// { dg-do compile }
+
+template <class>
+struct A;
+
+template <class T>
+struct A<T[]> { typedef int X; };
+
+template <class T> int foo (T&, typename A<T>::X = 0) { return 0; }
+
+struct B { int n, a[]; };
+
+void bar (B *b)
+{
+    foo (b->a);
+}
index d1af7e028fedb784dd2c7b14509f68984733331b..608b5be9f342cf11af0f8a5710ed77fd0c0cadbb 100644 (file)
@@ -7,5 +7,5 @@ struct S
   __extension__ unsigned char data[];
 };
 
-/* { dg-final { scan-ada-spec "array \\(0 .. 0\\)" } } */
+/* { dg-final { scan-ada-spec "array \\(size_t\\)" } } */
 /* { dg-final { cleanup-ada-spec } } */