diff mbox series

C++ PATCH for c++/82070, error with nested lambda capture

Message ID CADzB+2mTHE4qv7o1j=TMph1OcBYEEfooZxayT39Zx7wcY58D7w@mail.gmail.com
State New
Headers show
Series C++ PATCH for c++/82070, error with nested lambda capture | expand

Commit Message

Jason Merrill Sept. 6, 2017, 6:56 p.m. UTC
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 <jason@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 mbox series

Patch

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, [] {});
+}