From: Jason Merrill Date: Tue, 7 Apr 2009 03:50:49 +0000 (-0400) Subject: re PR c++/35146 (weird error in template function specialization) X-Git-Tag: releases/gcc-4.3.4~235 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2c4e6eb98aaeb8edd090d4edd1333b36d151e6d;p=thirdparty%2Fgcc.git 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: r145647 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 68ecd5836e49..4905a601d38f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2009-04-06 Jason Merrill + + 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-03-30 Jason Merrill PR c++/38030, 38850, 39070 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ded2b2f8c7a6..8cf6f410e64c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11811,9 +11811,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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4f93fa4eab01..8e70ccf97658 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-04-06 Jason Merrill + + PR c++/35146 + * g++.dg/template/fnspec1.C: New. + 2009-04-04 Jerry DeLisle PR libfortran/39528 diff --git a/gcc/testsuite/g++.dg/template/fnspec1.C b/gcc/testsuite/g++.dg/template/fnspec1.C new file mode 100644 index 000000000000..5d5324475a4d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/fnspec1.C @@ -0,0 +1,16 @@ +// PR c++/35146 + +template struct S {}; + +template struct ref; +template <> struct ref { typedef double result; }; + +template +void foo(typename ref::result, S*); +template <> +void foo(S, S*); // { dg-error "does not match" } +template <> +void foo(double alpha, S* x) +{ + alpha; x; +}