aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-04-04 21:34:18 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2018-04-04 21:34:18 +0200
commit628a15343e494e457c647347e879c69a62016e0c (patch)
treebe0e52b9e5a853ce7d421833b2bda0d3e3c369c3
parent001db6cf52711f785459558508ca6fa97e10bcae (diff)
downloadgcc-628a15343e494e457c647347e879c69a62016e0c.zip
gcc-628a15343e494e457c647347e879c69a62016e0c.tar.gz
gcc-628a15343e494e457c647347e879c69a62016e0c.tar.bz2
re PR c++/85146 (ICE with __direct_bases for declared but not defined struct)
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
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/pt.c21
-rw-r--r--gcc/cp/semantics.c70
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/ext/bases2.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/bases3.C13
7 files changed, 76 insertions, 55 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 04670a3..71bde98 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f7bacd0..2b49c6e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index dbbc766..eafc110 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ef243f6..59cac77 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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];
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ef7e772..7806777 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/ext/bases2.C b/gcc/testsuite/g++.dg/ext/bases2.C
index a8806dd..81c33fe 100644
--- a/gcc/testsuite/g++.dg/ext/bases2.C
+++ b/gcc/testsuite/g++.dg/ext/bases2.C
@@ -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
index 0000000..d4c43d4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/bases3.C
@@ -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;