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

Reply via email to