Substituting into the fold-expression was producing an
EXPR_PACK_EXPANSION, but it would be better to keep it as a
fold-expression.  tsubst_unary_left_fold et al try to do this, but
weren't recognizing the case where tsubst_pack_expansion returns a
TREE_VEC containing a single pack expansion.  In that case, let's just
return the pack expansion without the TREE_VEC, as we do earlier in
tsubst_pack_expansion for similar situations.

Tested x86_64-pc-linux-gnu, applying to trunk and 6.
commit 994ccc9de1117b6388859663cb9817e20ed66c50
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Aug 3 19:19:32 2016 -0400

        PR c++/72415 - member template with fold-expression constraint
    
        * pt.c (tsubst_pack_expansion): Pull a single pack expansion out
        of the TREE_VEC.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bf729ea..60c87e0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11160,6 +11160,12 @@ tsubst_pack_expansion (tree t, tree args, 
tsubst_flags_t complain,
       local_specializations = saved_local_specializations;
     }
   
+  /* If the dependent pack arguments were such that we end up with only a
+     single pack expansion again, there's no need to keep it in a TREE_VEC.  */
+  if (len == 1 && TREE_CODE (result) == TREE_VEC
+      && PACK_EXPANSION_P (TREE_VEC_ELT (result, 0)))
+    return TREE_VEC_ELT (result, 0);
+
   return result;
 }
 
diff --git a/gcc/testsuite/g++.dg/concepts/memfun2.C 
b/gcc/testsuite/g++.dg/concepts/memfun2.C
new file mode 100644
index 0000000..c186a18
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/memfun2.C
@@ -0,0 +1,21 @@
+// PR c++/72415
+// { dg-options "-std=c++1z -fconcepts" }
+
+template<int... Indices>
+struct indices {};
+
+template<typename Dummy>
+struct foo_type {
+    template<int... Indices>
+    static void impl(indices<Indices...>)
+        requires (... && (Indices, true));
+
+    static auto caller()
+    { return impl(indices<0, 1, 2> {}); }
+};
+
+int main()
+{
+    // internal compiler error: in satisfy_predicate_constraint, at 
cp/constraint.cc:2013
+    foo_type<void>::caller();
+}

Reply via email to