aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-05-23 20:45:44 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-05-23 20:45:44 +0000
commit29a1da1c303b0bca58faf0963ae250eb460c66ba (patch)
treea996ed17904d7204527c53eed8e2687ac420baa4 /gcc
parentb2a203c8e07fd3f8bb81f15780d6be9e6333f708 (diff)
downloadgcc-29a1da1c303b0bca58faf0963ae250eb460c66ba.zip
gcc-29a1da1c303b0bca58faf0963ae250eb460c66ba.tar.gz
gcc-29a1da1c303b0bca58faf0963ae250eb460c66ba.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c39
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/error21.C15
4 files changed, 57 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4cfa827..f6bcf57 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8db24ca..ca57676 100644
--- a/gcc/cp/pt.c
+++ b/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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bb4451d..eea1b80 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/template/error21.C b/gcc/testsuite/g++.dg/template/error21.C
new file mode 100644
index 0000000..c5f04f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error21.C
@@ -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" }