aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-03-27 10:27:00 -0400
committerJason Merrill <jason@gcc.gnu.org>2019-03-27 10:27:00 -0400
commitce4609958f8db5cd64ec1c3bec624a36d8b35812 (patch)
tree5fb7fdcf62bba0224c98e9af4d7bdbac59ac3b1e /gcc
parent079c81dabf6a5f2fdb054651ec78f74a590a4ad0 (diff)
downloadgcc-ce4609958f8db5cd64ec1c3bec624a36d8b35812.zip
gcc-ce4609958f8db5cd64ec1c3bec624a36d8b35812.tar.gz
gcc-ce4609958f8db5cd64ec1c3bec624a36d8b35812.tar.bz2
PR c++/86932 - missed SFINAE with empty pack.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae65.C15
3 files changed, 22 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 550b754..bce9b10 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 05d5371..dc982f3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..66790df
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae65.C
@@ -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" }
+}