]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/35146 (weird error in template function specialization)
authorJason Merrill <jason@redhat.com>
Tue, 7 Apr 2009 03:50:49 +0000 (23:50 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 7 Apr 2009 03:50:49 +0000 (23:50 -0400)
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

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/fnspec1.C [new file with mode: 0644]

index 68ecd5836e4905c9da8f1704c41aa5616c408961..4905a601d38f706dd06dc1f42511d9caebbc3863 100644 (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-03-30  Jason Merrill  <jason@redhat.com>
 
        PR c++/38030, 38850, 39070
index ded2b2f8c7a6c39b439c834b0be1d847452e5302..8cf6f410e64c696fa09ff0889b8a629b20742dde 100644 (file)
@@ -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;
 }
index 4f93fa4eab01b9057b933ed0153b1ca232d97d0f..8e70ccf9765843f229aa41f1401f570b419e93bf 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35146
+       * g++.dg/template/fnspec1.C: New.
+
 2009-04-04  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        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 (file)
index 0000000..5d53244
--- /dev/null
@@ -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;
+}