This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/35146


In this PR, when checking whether a particular function template specialization matches a particular function template, we successfully deduce template arguments and substitute them into the template pattern, but then never check whether that gives us the same signature as the specialization.

Tested x86_64-pc-linux-gnu, applied to trunk. I'll apply to 4.4 and 4.3 as well after testing there.

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.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3e3d4f2..92815c0 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/g++.dg/template/fnspec1.C b/gcc/testsuite/g++.dg/template/fnspec1.C
new file mode 100644
index 0000000..5d53244
--- /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;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]