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++/38543 (specialization of variadic function template)


The old code that compares the number of parameter types doesn't work in the age of variadic templates. Instead, we should take the deduced template arguments, substitute them in, and see if the result is what we're looking for.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 84857b9698edb306e9659b1cc3a9f63829689db3
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Apr 16 13:32:36 2012 -0400

    	PR c++/38543
    	* pt.c (determine_specialization): Instead of comparing the number
    	of parms, check that tsubst gives the right answer.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 171acb7..92c2326 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1839,6 +1839,7 @@ determine_specialization (tree template_id,
 	{
 	  tree decl_arg_types;
 	  tree fn_arg_types;
+	  tree insttype;
 
 	  /* In case of explicit specialization, we need to check if
 	     the number of template headers appearing in the specialization
@@ -1900,15 +1901,6 @@ determine_specialization (tree template_id,
 	  fn_arg_types 
 	    = skip_artificial_parms_for (fn, fn_arg_types);
 
-	  /* Check that the number of function parameters matches.
-	     For example,
-	       template <class T> void f(int i = 0);
-	       template <> void f<int>();
-	     The specialization f<int> is invalid but is not caught
-	     by get_bindings below.  */
-	  if (list_length (fn_arg_types) != list_length (decl_arg_types))
-	    continue;
-
 	  /* Function templates cannot be specializations; there are
 	     no partial specializations of functions.  Therefore, if
 	     the type of DECL does not match FN, there is no
@@ -1929,6 +1921,15 @@ determine_specialization (tree template_id,
 	       specialize TMPL will produce DECL.  */
 	    continue;
 
+	  /* Make sure that the deduced arguments actually work.  */
+	  insttype = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE);
+	  if (insttype == error_mark_node)
+	    continue;
+	  fn_arg_types
+	    = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (insttype));
+	  if (!compparms (fn_arg_types, decl_arg_types))
+	    continue;
+
 	  /* Save this template, and the arguments deduced.  */
 	  templates = tree_cons (targs, fn, templates);
 	}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic131.C b/gcc/testsuite/g++.dg/cpp0x/variadic131.C
new file mode 100644
index 0000000..3006f87
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic131.C
@@ -0,0 +1,11 @@
+// PR c++/38543
+// { dg-do compile { target c++11 } }
+
+template< typename ... T > void foo( T ... args );
+template<> void foo( ){}
+template<> void foo(int,double){}
+int main()
+{
+  foo( 0, 0.0 );
+  return 55;
+}

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