PR c++/86932 - missed SFINAE with empty pack.
authorJason Merrill <jason@redhat.com>
Wed, 27 Mar 2019 14:27:00 +0000 (10:27 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 27 Mar 2019 14:27:00 +0000 (10:27 -0400)
The issue here was that when processing the explicit template args in
fn_type_unification we added an empty argument pack for the parameter pack,
so we never tried to do any deduction for it, and therefore never looked at
its type.  We need that empty pack behavior for partial ordering, but we
don't want it here, so let's make it conditional on tf_partial.

* pt.c (coerce_template_parms): Don't add an empty pack if
tf_partial.
(fn_type_unification): Pass tf_partial to coerce_template_parms.

From-SVN: r269965

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

index 550b7541d9fc4fb6b2331ad806e19d19ad05549f..bce9b108723d1f591aadf4e51c95446edb8278b4 100644 (file)
@@ -1,5 +1,10 @@
 2019-03-26  Jason Merrill  <jason@redhat.com>
 
+       PR c++/86932 - missed SFINAE with empty pack.
+       * pt.c (coerce_template_parms): Don't add an empty pack if
+       tf_partial.
+       (fn_type_unification): Pass tf_partial to coerce_template_parms.
+
        PR c++/86429 - constexpr variable in lambda.
        PR c++/82643
        PR c++/87327
index 05d5371d8a6ff0fb04d286655a7551831411614a..dc982f3ed55a7babf04066d0bcccc40eb1a3395e 100644 (file)
@@ -8436,6 +8436,7 @@ coerce_template_parms (tree parms,
        arg = NULL_TREE;
 
       if (template_parameter_pack_p (TREE_VALUE (parm))
+         && (arg || !(complain & tf_partial))
          && !(arg && ARGUMENT_PACK_P (arg)))
         {
          /* Some arguments will be placed in the
@@ -20077,7 +20078,7 @@ fn_type_unification (tree fn,
         substitution context.  */
       explicit_targs
        = (coerce_template_parms (tparms, explicit_targs, NULL_TREE,
-                                 complain,
+                                 complain|tf_partial,
                                  /*require_all_args=*/false,
                                  /*use_default_args=*/false));
       if (explicit_targs == error_mark_node)
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae65.C b/gcc/testsuite/g++.dg/cpp0x/sfinae65.C
new file mode 100644 (file)
index 0000000..66790df
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/86932
+// { dg-do compile { target c++11 } }
+
+template<bool, typename T> struct enable_if { using type = T; };
+template<typename T> struct enable_if<false, T> { };
+
+template<typename> struct is_foo { static constexpr bool value = false; };
+
+// { dg-error "enable_if" "" { target *-*-* } .+1 }
+template<class U, typename enable_if<is_foo<U>::value, int>::type...> void f() {}
+
+int main()
+{
+  f<int>();                    // { dg-error "no match" }
+}