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(); +}