Here, strip_typedefs_expr was walking into PACK_EXPANSION_EXTRA_ARGS, which it shouldn't do. Fixed by using cp_tree_operand_length, which was created to address this sort of issue.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit bdf6657e3f32e903915046540c1dc6d875c32ea5 Author: Jason Merrill <ja...@redhat.com> Date: Fri Feb 2 11:08:04 2018 -0500 PR c++/84181 - ICE with lambda parm in template argument. * tree.c (strip_typedefs_expr): Use cp_tree_operand_length. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index e87c59659a5..c212c80ecf8 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1773,7 +1773,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes) gcc_assert (EXPR_P (t)); - n = TREE_OPERAND_LENGTH (t); + n = cp_tree_operand_length (t); ops = XALLOCAVEC (tree, n); type = TREE_TYPE (t); diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-targ1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-targ1.C new file mode 100644 index 00000000000..fa852492f61 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-targ1.C @@ -0,0 +1,16 @@ +// PR c++/84181 +// { dg-do compile { target c++14 } } + +template < int ... I > +struct A{}; + +template < typename T > +void f(){ + [](auto ... i){ + return A< decltype(i){} ... >{}; + }; +} + +int main(){ + f< int >(); +}