From: Jakub Jelinek Date: Wed, 4 Apr 2018 19:34:18 +0000 (+0200) Subject: re PR c++/85146 (ICE with __direct_bases for declared but not defined struct) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=628a15343e494e457c647347e879c69a62016e0c;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 04670a3acaa..71bde988630 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2018-04-04 Jakub Jelinek + + 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 PR c++/85006 - -fconcepts ICE with A return type diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f7bacd08c8f..2b49c6eb03f 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 dbbc7666721..eafc110dbde 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 ef243f6bf0a..59cac77f6b7 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 *vector = make_tree_vector(); - tree bases_vec = NULL_TREE; - vec *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 *vector = make_tree_vector (); + vec *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 **data = ((vec **) 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 * calculate_bases_helper (tree type) { - vec *vector = make_tree_vector(); + vec *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 *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 *vector = make_tree_vector (); tree bases_vec = NULL_TREE; unsigned i; vec *vbases; vec *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 *vbase_bases; - vbase_bases = calculate_bases_helper (BINFO_TYPE (binfo)); + vec *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 ef7e77271a1..7806777a363 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-04-04 Jakub Jelinek + + 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 PR target/85203 diff --git a/gcc/testsuite/g++.dg/ext/bases2.C b/gcc/testsuite/g++.dg/ext/bases2.C index a8806dde839..81c33fef736 100644 --- a/gcc/testsuite/g++.dg/ext/bases2.C +++ b/gcc/testsuite/g++.dg/ext/bases2.C @@ -5,7 +5,7 @@ template struct A {}; template 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 00000000000..d4c43d48327 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/bases3.C @@ -0,0 +1,13 @@ +// PR c++/85146 +// { dg-do compile { target c++11 } } + +template struct A {}; + +template struct B +{ + typedef A<__direct_bases(T)...> C; // { dg-error "incomplete type" } +}; + +struct X; + +B b;