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
This commit is contained in:
Jason Merrill 2010-07-16 17:05:16 -04:00 committed by Jason Merrill
parent f25669da4a
commit ebc258f1b3
4 changed files with 36 additions and 3 deletions

View file

@ -1,5 +1,10 @@
2010-07-16 Jason Merrill <jason@redhat.com>
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 <froydnj@codesourcery.com>

View file

@ -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))

View file

@ -1,3 +1,8 @@
2010-07-16 Jason Merrill <jason@redhat.com>
PR c++/32505
* g++.dg/template/partial8.C: New.
2010-07-16 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/guality/guality.exp: Run also c-c++-common/guality/ tests.

View file

@ -0,0 +1,4 @@
// PR c++/32505
template <class T> struct A { };
A<int*> a;
template <class T> struct A<T*> { }; // { dg-error "A<int\\*>" }