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:
parent
b2a203c8e0
commit
29a1da1c30
@ -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
|
||||
|
39
gcc/cp/pt.c
39
gcc/cp/pt.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
15
gcc/testsuite/g++.dg/template/error21.C
Normal file
15
gcc/testsuite/g++.dg/template/error21.C
Normal 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" }
|
Loading…
Reference in New Issue
Block a user