PR c++/38543
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Apr 2012 02:29:51 +0000 (02:29 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Apr 2012 02:29:51 +0000 (02:29 +0000)
* pt.c (determine_specialization): Instead of comparing the number
of parms, check that tsubst gives the right answer.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186522 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 1b7f4be..8746c64 100644 (file)
@@ -1,5 +1,9 @@
 2012-04-16  Jason Merrill  <jason@redhat.com>
 
+       PR c++/38543
+       * pt.c (determine_specialization): Instead of comparing the number
+       of parms, check that tsubst gives the right answer.
+
        PR c++/52008
        * pt.c (process_partial_specialization): Complain about a partial
        specialization with fewer args than primary template parms.
index d6144d5..0ca6993 100644 (file)
@@ -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);
        }
index 2acdffe..0b6fcf5 100644 (file)
@@ -1,5 +1,8 @@
 2012-04-16  Jason Merrill  <jason@redhat.com>
 
+       PR c++/38543
+       * g++.dg/cpp0x/variadic131.C: New.
+
        PR c++/52008
        * g++.dg/cpp0x/variadic130.C: New.
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic131.C b/gcc/testsuite/g++.dg/cpp0x/variadic131.C
new file mode 100644 (file)
index 0000000..3006f87
--- /dev/null
@@ -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;
+}