diff options
author | Jason Merrill <jason@redhat.com> | 2009-04-06 16:55:04 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-04-06 16:55:04 -0400 |
commit | 463ecaca844a0a834d86b804fea9a8bed120678c (patch) | |
tree | 288125d2703e3ee1ec38844d785486bf035c7f63 | |
parent | b6837b94d9916498b79b854728187361dde113a0 (diff) | |
download | gcc-463ecaca844a0a834d86b804fea9a8bed120678c.tar.gz |
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
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/fnspec1.C | 16 |
4 files changed, 49 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 40862578923..02440e516e0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3e3d4f250f2..92815c08267 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 40b0d240ee5..b4864a20dbb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/g++.dg/template/fnspec1.C b/gcc/testsuite/g++.dg/template/fnspec1.C new file mode 100644 index 00000000000..5d5324475a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/fnspec1.C @@ -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; +} |