diff mbox

C++ PATCH for c++/69743 (wrong overload resolution with variadic templates)

Message ID 56C7EBBD.7060601@redhat.com
State New
Headers show

Commit Message

Jason Merrill Feb. 20, 2016, 4:29 a.m. UTC
My change to tsubst_pack_expansion to handle the special case of T... 
revealed a latent bug whereby we were considering the trailing "void" 
when comparing two variadic templates.  When we then try to deduce one 
from the other we get a parameter of type "void", which results in 
substitution failure.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.
diff mbox

Patch

commit dfdc04172ec79a1a65f9e0d874556ace45915b99
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 19 18:22:24 2016 -0500

    	PR c++/69743
    	* call.c (remaining_arguments): No longer static.
    	* cp-tree.h: Declare it.
    	* pt.c (more_specialized_fn): Use it.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index cb71176..4226094 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1905,7 +1905,7 @@  add_candidate (struct z_candidate **candidates,
 /* Return the number of remaining arguments in the parameter list
    beginning with ARG.  */
 
-static int
+int
 remaining_arguments (tree arg)
 {
   int n;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7800ae8..3c23a83a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5612,6 +5612,7 @@  extern tree make_temporary_var_for_ref_to_temp	(tree, tree);
 extern bool type_has_extended_temps		(tree);
 extern tree strip_top_quals			(tree);
 extern bool reference_related_p			(tree, tree);
+extern int remaining_arguments			(tree);
 extern tree perform_implicit_conversion		(tree, tree, tsubst_flags_t);
 extern tree perform_implicit_conversion_flags	(tree, tree, tsubst_flags_t, int);
 extern tree build_integral_nontype_arg_conv	(tree, tree, tsubst_flags_t);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7308389..65edfa7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -20288,7 +20288,7 @@  more_specialized_fn (tree pat1, tree pat2, int len)
 
       if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION)
         {
-          int i, len2 = list_length (args2);
+          int i, len2 = remaining_arguments (args2);
           tree parmvec = make_tree_vec (1);
           tree argvec = make_tree_vec (len2);
           tree ta = args2;
@@ -20312,7 +20312,7 @@  more_specialized_fn (tree pat1, tree pat2, int len)
         }
       else if (TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
         {
-          int i, len1 = list_length (args1);
+          int i, len1 = remaining_arguments (args1);
           tree parmvec = make_tree_vec (1);
           tree argvec = make_tree_vec (len1);
           tree ta = args1;
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic167.C b/gcc/testsuite/g++.dg/cpp0x/variadic167.C
new file mode 100644
index 0000000..cada972
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic167.C
@@ -0,0 +1,18 @@ 
+// PR c++/69743
+// { dg-do compile { target c++11 } }
+
+template <typename D, typename... T>
+void f(int, T... d)
+{
+}
+
+template <typename D, typename... T>
+void f(T... d)
+{
+  f<D>(1, d...);
+}
+
+void g(void)
+{
+  f<long>(1.0);
+}