I was expecting that references to capture proxies would be resolved in the reconstructed lambda by normal name lookup, but that doesn't work in decltype, and processing the nested lambda really wants to find the new capture proxy, not the captured variable.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit f9a1fe6d129418e72c68d0d1d9d35089ba7817b2 Author: Jason Merrill <ja...@redhat.com> Date: Wed Sep 6 13:41:58 2017 -0400 PR c++/82070 - error with nested lambda capture * pt.c (tsubst_expr) [DECL_EXPR]: Register capture proxies with register_local_specialization. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index eb27f6a..4a65e31 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15985,8 +15985,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, else if (is_capture_proxy (decl) && !DECL_TEMPLATE_INSTANTIATION (current_function_decl)) { - /* We're in tsubst_lambda_expr, we've already inserted new capture - proxies, and uses will find them with lookup_name. */ + /* We're in tsubst_lambda_expr, we've already inserted a new + capture proxy, so look it up and register it. */ + tree inst = lookup_name (DECL_NAME (decl)); + gcc_assert (inst != decl && is_capture_proxy (inst)); + register_local_specialization (inst, decl); break; } else if (DECL_IMPLICIT_TYPEDEF_P (decl) diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested7.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested7.C new file mode 100644 index 0000000..7403315 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested7.C @@ -0,0 +1,17 @@ +// PR c++/82070 +// { dg-do compile { target c++11 } } + +namespace a { +template <typename b> +void +c (int, int, b d) +{ + [d] { [d] {}; }; +} +} +void +e () +{ + int f; + a::c (f, 3, [] {}); +}