We ICE here because we are accessing call_args even though it's empty: (gdb) p (*call_args).is_empty() $5 = true
It's empty because the pack processed by tsubst_pack_expansion expanded into an empty vector, so nothing got pushed onto call_args. So handle that, and also handle pushing 'this' properly when call_args is empty. Bootstrapped/regtested on x86_64-linux, ok for trunk and 9? 2019-05-20 Marek Polacek <pola...@redhat.com> PR c++/90548 - ICE with generic lambda and empty pack. * pt.c (tsubst_copy_and_build): Handle empty call args vector properly. * g++.dg/cpp1y/lambda-generic-90548.C: New test. diff --git gcc/cp/pt.c gcc/cp/pt.c index 3519c7a34a6..d9b99740947 100644 --- gcc/cp/pt.c +++ gcc/cp/pt.c @@ -18880,7 +18880,10 @@ tsubst_copy_and_build (tree t, /* We aren't going to do normal overload resolution, so force the template-id to resolve. */ function = resolve_nondeduced_context (function, complain); - for (unsigned i = 0; i < nargs; ++i) + /* There's no guarantee that there are any args; e.g., we could've + expanded an empty pack. */ + const bool empty_p = call_args->is_empty (); + for (unsigned i = 0; i < nargs && !empty_p; ++i) { /* In a thunk, pass through args directly, without any conversions. */ @@ -18891,12 +18894,18 @@ tsubst_copy_and_build (tree t, } if (thisarg) { - /* Shift the other args over to make room. */ - tree last = (*call_args)[nargs - 1]; - vec_safe_push (call_args, last); - for (int i = nargs-1; i > 0; --i) - (*call_args)[i] = (*call_args)[i-1]; - (*call_args)[0] = thisarg; + /* If there are no other args, just push 'this'. */ + if (empty_p) + vec_safe_push (call_args, thisarg); + else + { + /* Otherwise, shift the other args over to make room. */ + tree last = (*call_args)[nargs - 1]; + vec_safe_push (call_args, last); + for (int i = nargs-1; i > 0; --i) + (*call_args)[i] = (*call_args)[i-1]; + (*call_args)[0] = thisarg; + } } ret = build_call_a (function, call_args->length (), call_args->address ()); diff --git gcc/testsuite/g++.dg/cpp1y/lambda-generic-90548.C gcc/testsuite/g++.dg/cpp1y/lambda-generic-90548.C new file mode 100644 index 00000000000..beaffc29cfd --- /dev/null +++ gcc/testsuite/g++.dg/cpp1y/lambda-generic-90548.C @@ -0,0 +1,8 @@ +// PR c++/90548 +// { dg-do compile { target c++14 } } + +struct S { S (void ()); }; + +S foo([] (auto...) {}); +S foo2{[] (auto...) {}}; +S foo3 = {[] (auto...) {}};