re PR c++/85146 (ICE with __direct_bases for declared but not defined struct)
authorJakub Jelinek <jakub@redhat.com>
Wed, 4 Apr 2018 19:34:18 +0000 (21:34 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 4 Apr 2018 19:34:18 +0000 (21:34 +0200)
PR c++/85146
* cp-tree.h (calculate_bases, calculate_direct_bases): Add complain
argument.
* semantics.c (calculate_bases): Add complain argument.  Use
complete_type_or_maybe_complain instead of just complete_type and
return an empty vector if it fails.  Move make_tree_vector () call
after early return.  Formatting fixes.
(calculate_direct_bases): Likewise.  Call release_tree_vector at the
end.
(dfs_calculate_bases_post, calculate_bases_helper): Formatting fixes.
* pt.c (tsubst_pack_expansion): Adjust calculate_bases and
calculate_direct_bases callers, formatting fixes.

* g++.dg/ext/bases2.C: Expect extra error diagnostics.
* g++.dg/ext/bases3.C: New test.

From-SVN: r259101

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/bases2.C
gcc/testsuite/g++.dg/ext/bases3.C [new file with mode: 0644]

index 04670a3acaa6d1222eb31a6b7335bdf741771edb..71bde9886301c950a583a2277dc58d25b6a91ba3 100644 (file)
@@ -1,3 +1,18 @@
+2018-04-04  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/85146
+       * cp-tree.h (calculate_bases, calculate_direct_bases): Add complain
+       argument.
+       * semantics.c (calculate_bases): Add complain argument.  Use
+       complete_type_or_maybe_complain instead of just complete_type and
+       return an empty vector if it fails.  Move make_tree_vector () call
+       after early return.  Formatting fixes.
+       (calculate_direct_bases): Likewise.  Call release_tree_vector at the
+       end.
+       (dfs_calculate_bases_post, calculate_bases_helper): Formatting fixes.
+       * pt.c (tsubst_pack_expansion): Adjust calculate_bases and
+       calculate_direct_bases callers, formatting fixes.
+
 2018-04-04  Jason Merrill  <jason@redhat.com>
 
        PR c++/85006 - -fconcepts ICE with A<auto...> return type
index f7bacd08c8f896153b653f285cbfd975b6390784..2b49c6eb03fcea77f208dbc1108f11df9eb0d873 100644 (file)
@@ -6870,9 +6870,9 @@ extern cp_expr finish_id_expression               (tree, tree, tree,
                                                  location_t);
 extern tree finish_typeof                      (tree);
 extern tree finish_underlying_type             (tree);
-extern tree calculate_bases                     (tree);
+extern tree calculate_bases                     (tree, tsubst_flags_t);
 extern tree finish_bases                        (tree, bool);
-extern tree calculate_direct_bases              (tree);
+extern tree calculate_direct_bases              (tree, tsubst_flags_t);
 extern tree finish_offsetof                    (tree, tree, location_t);
 extern void finish_decl_cleanup                        (tree, tree);
 extern void finish_eh_cleanup                  (tree);
index dbbc76667212ddf63998dfc7861238c90f307192..eafc110dbde9578b933cadf022425c0c34910c7a 100644 (file)
@@ -11743,15 +11743,18 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
       int level = 0;
 
       if (TREE_CODE (parm_pack) == BASES)
-       {
-        gcc_assert (parm_pack == pattern);
-         if (BASES_DIRECT (parm_pack))
-           return calculate_direct_bases (tsubst_expr (BASES_TYPE (parm_pack),
-                                                        args, complain, in_decl, false));
-         else
-           return calculate_bases (tsubst_expr (BASES_TYPE (parm_pack),
-                                                 args, complain, in_decl, false));
-       }
+       {
+         gcc_assert (parm_pack == pattern);
+         if (BASES_DIRECT (parm_pack))
+           return calculate_direct_bases (tsubst_expr (BASES_TYPE (parm_pack),
+                                                       args, complain,
+                                                       in_decl, false),
+                                          complain);
+         else
+           return calculate_bases (tsubst_expr (BASES_TYPE (parm_pack),
+                                                args, complain, in_decl,
+                                                false), complain);
+       }
       else if (builtin_pack_call_p (parm_pack))
        {
          /* ??? Support use in other patterns.  */
index ef243f6bf0a764aac0fc60998348cd3f83972c29..59cac77f6b70a4a67e0a39cccd853cd7706c6164 100644 (file)
@@ -3885,49 +3885,36 @@ finish_underlying_type (tree type)
 }
 
 /* Implement the __direct_bases keyword: Return the direct base classes
-   of type */
+   of type */
 
 tree
-calculate_direct_bases (tree type)
+calculate_direct_bases (tree type, tsubst_flags_t complain)
 {
-  vec<tree, va_gc> *vector = make_tree_vector();
-  tree bases_vec = NULL_TREE;
-  vec<tree, va_gc> *base_binfos;
-  tree binfo;
-  unsigned i;
-
-  complete_type (type);
-
-  if (!NON_UNION_CLASS_TYPE_P (type))
+  if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
+      || !NON_UNION_CLASS_TYPE_P (type))
     return make_tree_vec (0);
 
-  base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
+  vec<tree, va_gc> *vector = make_tree_vector ();
+  vec<tree, va_gc> *base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
+  tree binfo;
+  unsigned i;
 
   /* Virtual bases are initialized first */
   for (i = 0; base_binfos->iterate (i, &binfo); i++)
-    {
-      if (BINFO_VIRTUAL_P (binfo))
-       {
-         vec_safe_push (vector, binfo);
-       }
-    }
+    if (BINFO_VIRTUAL_P (binfo))
+      vec_safe_push (vector, binfo);
 
   /* Now non-virtuals */
   for (i = 0; base_binfos->iterate (i, &binfo); i++)
-    {
-      if (!BINFO_VIRTUAL_P (binfo))
-       {
-         vec_safe_push (vector, binfo);
-       }
-    }
-
+    if (!BINFO_VIRTUAL_P (binfo))
+      vec_safe_push (vector, binfo);
 
-  bases_vec = make_tree_vec (vector->length ());
+  tree bases_vec = make_tree_vec (vector->length ());
 
   for (i = 0; i < vector->length (); ++i)
-    {
-      TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
-    }
+    TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
+
+  release_tree_vector (vector);
   return bases_vec;
 }
 
@@ -3949,9 +3936,7 @@ dfs_calculate_bases_post (tree binfo, void *data_)
 {
   vec<tree, va_gc> **data = ((vec<tree, va_gc> **) data_);
   if (!BINFO_VIRTUAL_P (binfo))
-    {
-      vec_safe_push (*data, BINFO_TYPE (binfo));
-    }
+    vec_safe_push (*data, BINFO_TYPE (binfo));
   return NULL_TREE;
 }
 
@@ -3959,7 +3944,7 @@ dfs_calculate_bases_post (tree binfo, void *data_)
 static vec<tree, va_gc> *
 calculate_bases_helper (tree type)
 {
-  vec<tree, va_gc> *vector = make_tree_vector();
+  vec<tree, va_gc> *vector = make_tree_vector ();
 
   /* Now add non-virtual base classes in order of construction */
   if (TYPE_BINFO (type))
@@ -3969,26 +3954,25 @@ calculate_bases_helper (tree type)
 }
 
 tree
-calculate_bases (tree type)
+calculate_bases (tree type, tsubst_flags_t complain)
 {
-  vec<tree, va_gc> *vector = make_tree_vector();
+  if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
+      || !NON_UNION_CLASS_TYPE_P (type))
+    return make_tree_vec (0);
+
+  vec<tree, va_gc> *vector = make_tree_vector ();
   tree bases_vec = NULL_TREE;
   unsigned i;
   vec<tree, va_gc> *vbases;
   vec<tree, va_gc> *nonvbases;
   tree binfo;
 
-  complete_type (type);
-
-  if (!NON_UNION_CLASS_TYPE_P (type))
-    return make_tree_vec (0);
-
   /* First go through virtual base classes */
   for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0;
        vec_safe_iterate (vbases, i, &binfo); i++)
     {
-      vec<tree, va_gc> *vbase_bases;
-      vbase_bases = calculate_bases_helper (BINFO_TYPE (binfo));
+      vec<tree, va_gc> *vbase_bases
+       = calculate_bases_helper (BINFO_TYPE (binfo));
       vec_safe_splice (vector, vbase_bases);
       release_tree_vector (vbase_bases);
     }
@@ -4002,7 +3986,7 @@ calculate_bases (tree type)
   if (vector->length () > 1)
     {
       /* Last element is entire class, so don't copy */
-      bases_vec = make_tree_vec (vector->length() - 1);
+      bases_vec = make_tree_vec (vector->length () - 1);
 
       for (i = 0; i < vector->length () - 1; ++i)
        TREE_VEC_ELT (bases_vec, i) = (*vector)[i];
index ef7e77271a1cf50403af75a2a121264427e35b7f..7806777a3637a3a3bfc1b8f2394286669456a1d6 100644 (file)
@@ -1,3 +1,9 @@
+2018-04-04  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/85146
+       * g++.dg/ext/bases2.C: Expect extra error diagnostics.
+       * g++.dg/ext/bases3.C: New test.
+
 2018-04-04  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        PR target/85203
index a8806dde83926b18b4512f359454a58a9709a99b..81c33fef7367317efff77e88cda1dc6ae3b1c694 100644 (file)
@@ -5,7 +5,7 @@ template<typename...> struct A {};
 
 template<typename T> struct B
 {
-  typedef A<__bases(T)...> C;
+  typedef A<__bases(T)...> C;  // { dg-error "incomplete type" }
 };
 
 struct X {};
diff --git a/gcc/testsuite/g++.dg/ext/bases3.C b/gcc/testsuite/g++.dg/ext/bases3.C
new file mode 100644 (file)
index 0000000..d4c43d4
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/85146
+// { dg-do compile { target c++11 } }
+
+template<typename...> struct A {};
+
+template<typename T> struct B
+{
+  typedef A<__direct_bases(T)...> C;   // { dg-error "incomplete type" }
+};
+
+struct X;
+
+B<X> b;