PR c++/71147 - [6 Regression] Flexible array member wrongly rejected in template
authorMartin Sebor <msebor@redhat.com>
Tue, 24 May 2016 20:29:36 +0000 (20:29 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 24 May 2016 20:29:36 +0000 (14:29 -0600)
gcc/ChangeLog:
2016-05-24  Martin Sebor  <msebor@redhat.com>

PR c++/71147
* gcc/tree.h (complete_or_array_type_p): New inline function.

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

PR c++/71147
* g++.dg/ext/flexary16.C: New test.

gcc/cp/ChangeLog:
2016-05-24  Martin Sebor  <msebor@redhat.com>

PR c++/71147
* decl.c (layout_var_decl, grokdeclarator): Use complete_or_array_type_p.
* pt.c (instantiate_class_template_1): Try to complete the element
type of a flexible array member.
(can_complete_type_without_circularity): Handle arrays of unknown bound.
* typeck.c (complete_type): Also complete the type of the elements of
arrays with an unspecified bound.

From-SVN: r236664

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/flexary16.C [new file with mode: 0644]
gcc/tree.h

index 8c61f1d153921ec2b75fcb2df0979d812b224f71..b07aa808891687a5ca7132af76fa04bda8b8c47b 100644 (file)
@@ -1,3 +1,8 @@
+2016-05-24  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/71147
+       * gcc/tree.h (complete_or_array_type_p): New inline function.
+
 2016-05-24  Jakub Jelinek  <jakub@redhat.com>
 
        * config/i386/i386.h (TARGET_AVOID_4BYTE_PREFIXES): Define.
index 4e06a71e7ca4d414c0b168eaab3423403067a1ef..5e7eb3d0e4cff043059e8d446226c25a2dfa53d9 100644 (file)
@@ -1,3 +1,13 @@
+2016-05-24  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/71147
+       * decl.c (layout_var_decl, grokdeclarator): Use complete_or_array_type_p.
+       * pt.c (instantiate_class_template_1): Try to complete the element
+       type of a flexible array member.
+       (can_complete_type_without_circularity): Handle arrays of unknown bound.
+       * typeck.c (complete_type): Also complete the type of the elements of
+       arrays with an unspecified bound.
+
 2016-05-24  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/69872
index 7a69711bdb1973a119ace70ea6b9605c1e884763..ef5fd665b4632b1d2e3ae359fb0b3e139cf653fc 100644 (file)
@@ -5305,10 +5305,7 @@ layout_var_decl (tree decl)
     complete_type (type);
   if (!DECL_SIZE (decl)
       && TREE_TYPE (decl) != error_mark_node
-      && (COMPLETE_TYPE_P (type)
-         || (TREE_CODE (type) == ARRAY_TYPE
-             && !TYPE_DOMAIN (type)
-             && COMPLETE_TYPE_P (TREE_TYPE (type)))))
+      && complete_or_array_type_p (type))
     layout_decl (decl, 0);
 
   if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE)
@@ -11165,8 +11162,7 @@ grokdeclarator (const cp_declarator *declarator,
          }
        else if (!staticp && !dependent_type_p (type)
                 && !COMPLETE_TYPE_P (complete_type (type))
-                && (TREE_CODE (type) != ARRAY_TYPE
-                    || !COMPLETE_TYPE_P (TREE_TYPE (type))
+                && (!complete_or_array_type_p (type)
                     || initialized == 0))
          {
            if (TREE_CODE (type) != ARRAY_TYPE
index 3e07fb0b6e0a32fcfd86079f0882238ab17dcd28..df3d634687d4f16e7b23c78ed30369b8b2e3ff16 100644 (file)
@@ -9555,7 +9555,7 @@ can_complete_type_without_circularity (tree type)
     return 0;
   else if (COMPLETE_TYPE_P (type))
     return 1;
-  else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
+  else if (TREE_CODE (type) == ARRAY_TYPE)
     return can_complete_type_without_circularity (TREE_TYPE (type));
   else if (CLASS_TYPE_P (type)
           && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
@@ -10120,17 +10120,12 @@ instantiate_class_template_1 (tree type)
                          if (can_complete_type_without_circularity (rtype))
                            complete_type (rtype);
 
-                          if (TREE_CODE (r) == FIELD_DECL
-                              && TREE_CODE (rtype) == ARRAY_TYPE
-                              && COMPLETE_TYPE_P (TREE_TYPE (rtype))
-                              && !COMPLETE_TYPE_P (rtype))
-                            {
-                              /* Flexible array mmembers of elements
-                                 of complete type have an incomplete type
-                                 and that's okay.  */
-                            }
-                          else if (!COMPLETE_TYPE_P (rtype))
+                         if (!complete_or_array_type_p (rtype))
                            {
+                             /* If R's type couldn't be completed and
+                                it isn't a flexible array member (whose
+                                type is incomplete by definition) give
+                                an error.  */
                              cxx_incomplete_type_error (r, rtype);
                              TREE_TYPE (r) = error_mark_node;
                            }
index 8b3fec66250913875d5cdd3e182eba0e01f7bd0d..f68c2a34024cf14a4f752fe72945d1a54f8c2a0f 100644 (file)
@@ -112,7 +112,7 @@ complete_type (tree type)
 
   if (type == error_mark_node || COMPLETE_TYPE_P (type))
     ;
-  else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
+  else if (TREE_CODE (type) == ARRAY_TYPE)
     {
       tree t = complete_type (TREE_TYPE (type));
       unsigned int needs_constructing, has_nontrivial_dtor;
index d88618eebb29e8c97fc8a57b821787feff93351c..6c03e26718ba1715ee3ce5cbc64d73b81761c5e3 100644 (file)
@@ -1,3 +1,8 @@
+2016-05-24  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/71147
+       * g++.dg/ext/flexary16.C: New test.
+
 2016-05-24  Ilya Verbin  <ilya.verbin@intel.com>
 
        * gcc.target/i386/avx-ceil-sfix-2-vec.c: Define __NO_MATH_INLINES before
diff --git a/gcc/testsuite/g++.dg/ext/flexary16.C b/gcc/testsuite/g++.dg/ext/flexary16.C
new file mode 100644 (file)
index 0000000..a3e040d
--- /dev/null
@@ -0,0 +1,37 @@
+// PR c++/71147 - [6 Regression] Flexible array member wrongly rejected
+//   in template
+// { dg-do compile }
+
+template <typename>
+struct container
+{
+  struct elem {
+    unsigned u;
+  };
+
+  struct incomplete {
+    int x;
+    elem array[];
+  };
+};
+
+unsigned f (container<void>::incomplete* i)
+{
+  return i->array [0].u;
+}
+
+
+template <typename T>
+struct D: container<T>
+{
+  struct S {
+    int x;
+    typename container<T>::elem array[];
+  };
+};
+
+
+unsigned g (D<void>::S *s)
+{
+  return s->array [0].u;
+}
index 2510d166ea6c456f9863e74c1bcfdb9d43fc676b..90413fcf2090043619e8bf190c11c066f63caa74 100644 (file)
@@ -4753,6 +4753,17 @@ ptrofftype_p (tree type)
          && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (sizetype));
 }
 
+/* Return true if the argument is a complete type or an array
+   of unknown bound (whose type is incomplete but) whose elements
+   have complete type.  */
+static inline bool
+complete_or_array_type_p (const_tree type)
+{
+  return COMPLETE_TYPE_P (type)
+         || (TREE_CODE (type) == ARRAY_TYPE
+            && COMPLETE_TYPE_P (TREE_TYPE (type)));
+}
+
 extern tree strip_float_extensions (tree);
 extern int really_constant_p (const_tree);
 extern bool decl_address_invariant_p (const_tree);