In this testcase we went to instantiate the reference to 'c' in the innermost lambda, looked it up, found the capture proxy in the middle lambda, decided that this was wrong because it's in a different function from the 'c' variable, tried to build a new version of 'c' for constant/type evaluation, and failed because 'c' isn't constant.
We should accept the capture proxy. Tested x86_64-pc-linux-gnu, applying to trunk.
commit d9f158fa405ee1124206cc5423f1483ec09b323e Author: Jason Merrill <ja...@redhat.com> Date: Fri Apr 7 17:09:22 2017 -0400 PR c++/80267 - ICE with nested capture of reference PR c++/60992 * pt.c (tsubst_copy): Handle lookup finding a capture proxy. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f9f4921..2d1e81f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14566,7 +14566,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) { /* First try name lookup to find the instantiation. */ r = lookup_name (DECL_NAME (t)); - if (r) + if (r && !is_capture_proxy (r)) { /* Make sure that the one we found is the one we want. */ tree ctx = DECL_CONTEXT (t); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested6.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested6.C new file mode 100644 index 0000000..58dfe3c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested6.C @@ -0,0 +1,12 @@ +// PR c++/80267 +// { dg-do compile { target c++11 } } + +template <typename> void a() { + int b; + auto &c = b; + [&] { + c; + [&] { c; }; + }; +} +void d() { a<int>(); }