re PR c++/35146 (weird error in template function specialization)

PR c++/35146
	* pt.c (fn_type_unification): For DEDUCE_EXACT check that
	the deduced template arguments give us the parameter types
	we're looking for.

From-SVN: r145625
This commit is contained in:
Jason Merrill 2009-04-06 16:55:04 -04:00 committed by Jason Merrill
parent b6837b94d9
commit 463ecaca84
4 changed files with 49 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2009-04-06 Jason Merrill <jason@redhat.com>
PR c++/35146
* pt.c (fn_type_unification): For DEDUCE_EXACT check that
the deduced template arguments give us the parameter types
we're looking for.
2009-04-05 Giovanni Bajo <giovannibajo@libero.it>
Jason Merrill <jason@redhat.com>

View File

@ -12301,9 +12301,27 @@ fn_type_unification (tree fn,
the corresponding deduced argument values. If the
substitution results in an invalid type, as described above,
type deduction fails. */
if (tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE)
== error_mark_node)
return 1;
{
tree substed = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE);
if (substed == error_mark_node)
return 1;
/* If we're looking for an exact match, check that what we got
is indeed an exact match. It might not be if some template
parameters are used in non-deduced contexts. */
if (strict == DEDUCE_EXACT)
{
tree sarg
= skip_artificial_parms_for (fn, TYPE_ARG_TYPES (substed));
tree arg = args;
if (return_type)
sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
for (; arg && sarg;
arg = TREE_CHAIN (arg), sarg = TREE_CHAIN (sarg))
if (!same_type_p (TREE_VALUE (arg), TREE_VALUE (sarg)))
return 1;
}
}
return result;
}

View File

@ -1,3 +1,8 @@
2009-04-06 Jason Merrill <jason@redhat.com>
PR c++/35146
* g++.dg/template/fnspec1.C: New.
2009-04-06 Laurent GUERBY <laurent@guerby.net>
* lib/gnat.exp: Handle multilib.

View File

@ -0,0 +1,16 @@
// PR c++/35146
template <typename T> struct S {};
template <typename R> struct ref;
template <> struct ref<double> { typedef double result; };
template <typename T>
void foo(typename ref<T>::result, S<T>*);
template <>
void foo(S<double>, S<double>*); // { dg-error "does not match" }
template <>
void foo(double alpha, S<double>* x)
{
alpha; x;
}