From ebc258f1b3474932a21d56758fd28a45e03ae984 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 16 Jul 2010 17:05:16 -0400 Subject: [PATCH] re PR c++/32505 (Partial specialization halfway accepted after instantiation) PR c++/32505 * pt.c (process_partial_specialization): Diagnose partial specialization after instantiation. (most_specialized_class): Add complain parm. From-SVN: r162269 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/pt.c | 25 +++++++++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/partial8.C | 4 ++++ 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/partial8.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fc297132bf3..79598d1d3cd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2010-07-16 Jason Merrill + PR c++/32505 + * pt.c (process_partial_specialization): Diagnose partial + specialization after instantiation. + (most_specialized_class): Add complain parm. + * ptree.c (cxx_print_xnode): Handle TEMPLATE_INFO. 2010-07-15 Nathan Froyd diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ef6e8e94d6a..3259043f4ae 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -158,7 +158,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static void regenerate_decl_from_template (tree, tree); -static tree most_specialized_class (tree, tree); +static tree most_specialized_class (tree, tree, tsubst_flags_t); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); @@ -3831,6 +3831,7 @@ process_partial_specialization (tree decl) tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs); tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); tree inner_parms; + tree inst; int nargs = TREE_VEC_LENGTH (inner_args); int ntparms; int i; @@ -4045,6 +4046,22 @@ process_partial_specialization (tree decl) = tree_cons (specargs, inner_parms, DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; + + for (inst = DECL_TEMPLATE_INSTANTIATIONS (maintmpl); inst; + inst = TREE_CHAIN (inst)) + { + tree inst_type = TREE_VALUE (inst); + if (COMPLETE_TYPE_P (inst_type) + && CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type)) + { + tree spec = most_specialized_class (inst_type, maintmpl, tf_none); + if (spec && TREE_TYPE (spec) == type) + permerror (input_location, + "partial specialization of %qT after instantiation " + "of %qT", type, inst_type); + } + } + return decl; } @@ -7749,7 +7766,7 @@ instantiate_class_template (tree type) /* Determine what specialization of the original template to instantiate. */ - t = most_specialized_class (type, templ); + t = most_specialized_class (type, templ, tf_warning_or_error); if (t == error_mark_node) { TYPE_BEING_DEFINED (type) = 1; @@ -15974,7 +15991,7 @@ most_general_template (tree decl) returned. */ static tree -most_specialized_class (tree type, tree tmpl) +most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain) { tree list = NULL_TREE; tree t; @@ -16094,6 +16111,8 @@ most_specialized_class (tree type, tree tmpl) { const char *str; char *spaces = NULL; + if (!(complain & tf_error)) + return error_mark_node; error ("ambiguous class template instantiation for %q#T", type); str = TREE_CHAIN (list) ? _("candidates are:") : _("candidate is:"); for (t = list; t; t = TREE_CHAIN (t)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fa9f59674bf..a693c5c521c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-07-16 Jason Merrill + + PR c++/32505 + * g++.dg/template/partial8.C: New. + 2010-07-16 Jakub Jelinek * gcc.dg/guality/guality.exp: Run also c-c++-common/guality/ tests. diff --git a/gcc/testsuite/g++.dg/template/partial8.C b/gcc/testsuite/g++.dg/template/partial8.C new file mode 100644 index 00000000000..4db7e18689e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial8.C @@ -0,0 +1,4 @@ +// PR c++/32505 +template struct A { }; +A a; +template struct A { }; // { dg-error "A" }