re PR c++/20173 (gcc accepts invalid partial specialization attempt of member function)

PR c++/20173
	* pt.c (determine_specialization): Disallow partial
	specializations of templates.
	PR c++/20173
	* g++.dg/template/error21.C: New test.

From-SVN: r114023
This commit is contained in:
Mark Mitchell 2006-05-23 20:45:44 +00:00 committed by Mark Mitchell
parent b2a203c8e0
commit 29a1da1c30
4 changed files with 57 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2006-05-23 Mark Mitchell <mark@codesourcery.com>
PR c++/20173
* pt.c (determine_specialization): Disallow partial
specializations of templates.
2006-05-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/27716

View File

@ -150,7 +150,6 @@ static tree get_template_base (tree, tree, tree, tree);
static tree try_class_unification (tree, tree, tree, tree);
static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
tree, tree);
static tree determine_specialization (tree, tree, tree *, int, int);
static int template_args_equal (tree, tree);
static void tsubst_default_arguments (tree);
static tree for_each_template_parm_r (tree *, int *, void *);
@ -1321,6 +1320,11 @@ print_candidates (tree fns)
template classes that appeared in the name of the function. See
check_explicit_specialization for a more accurate description.
TSK indicates what kind of template declaration (if any) is being
declared. TSK_TEMPLATE indicates that the declaration given by
DECL, though a FUNCTION_DECL, has template parameters, and is
therefore a template function.
The template args (those explicitly specified and those deduced)
are output in a newly created vector *TARGS_OUT.
@ -1332,7 +1336,8 @@ determine_specialization (tree template_id,
tree decl,
tree* targs_out,
int need_member_template,
int template_count)
int template_count,
tmpl_spec_kind tsk)
{
tree fns;
tree targs;
@ -1450,6 +1455,18 @@ determine_specialization (tree template_id,
(current_template_parms))))
continue;
/* Function templates cannot be specializations; there are
no partial specializations of functions. Therefore, if
the type of DECL does not match FN, there is no
match. */
if (tsk == tsk_template)
{
if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
decl_arg_types))
candidates = tree_cons (NULL_TREE, fn, candidates);
continue;
}
/* See whether this function might be a specialization of this
template. */
targs = get_bindings (fn, decl, explicit_targs, /*check_ret=*/true);
@ -1576,10 +1593,14 @@ determine_specialization (tree template_id,
/* We have one, and exactly one, match. */
if (candidates)
{
tree fn = TREE_VALUE (candidates);
/* DECL is a re-declaration of a template function. */
if (TREE_CODE (fn) == TEMPLATE_DECL)
return fn;
/* It was a specialization of an ordinary member function in a
template class. */
*targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates)));
return DECL_TI_TEMPLATE (TREE_VALUE (candidates));
*targs_out = copy_node (DECL_TI_ARGS (fn));
return DECL_TI_TEMPLATE (fn);
}
/* It was a specialization of a template. */
@ -2042,7 +2063,8 @@ check_explicit_specialization (tree declarator,
tmpl = determine_specialization (declarator, decl,
&targs,
member_specialization,
template_count);
template_count,
tsk);
if (!tmpl || tmpl == error_mark_node)
/* We couldn't figure out what this declaration was
@ -2088,8 +2110,8 @@ check_explicit_specialization (tree declarator,
revert_static_member_fn (decl);
/* If this is a specialization of a member template of a
template class. In we want to return the TEMPLATE_DECL,
not the specialization of it. */
template class, we want to return the TEMPLATE_DECL, not
the specialization of it. */
if (tsk == tsk_template)
{
SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
@ -5163,7 +5185,8 @@ tsubst_friend_function (tree decl, tree args)
tmpl = determine_specialization (template_id, new_friend,
&new_args,
/*need_member_template=*/0,
TREE_VEC_LENGTH (args));
TREE_VEC_LENGTH (args),
tsk_none);
return instantiate_template (tmpl, new_args, tf_error);
}

View File

@ -1,3 +1,8 @@
2006-05-23 Mark Mitchell <mark@codesourcery.com>
PR c++/20173
* g++.dg/template/error21.C: New test.
2006-05-23 Kazu Hirata <kazu@codesourcery.com>
PR target/27696

View File

@ -0,0 +1,15 @@
// PR c++/20173
template<typename AT>
struct A{
template<typename T>
void function(T){}
};
template<>
template<typename T>
void A<int>::function(T){}
template<>
template<typename T>
void A<double>::function(T*){} // { dg-error "match" }