Patchwork C++ PATCH for c++/56710 (ICE with local variable __t in lambda)

login
register
mail settings
Submitter Jason Merrill
Date March 28, 2013, 6:11 p.m.
Message ID <515487E8.8070803@redhat.com>
Download mbox | patch
Permalink /patch/232158/
State New
Headers show

Comments

Jason Merrill - March 28, 2013, 6:11 p.m.
The compiler was getting confused when an implicit capture added a __t 
class binding and then tried to pop the __t local variable.  But we 
don't need to push the closure members as bindings at all, since we now 
use capture proxies for name resolution.

The second patch fixes a -Wshadow issue I noticed while looking at this.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 03426fb7d994c8eb6bf7f1097c45f6079e8227d5
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 27 15:47:58 2013 -0400

    	PR c++/56710
    	* semantics.c (finish_member_declaration): Don't push closure
    	members.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0b8e2f7..ad1c209 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2719,8 +2719,10 @@  finish_member_declaration (tree decl)
 					      /*friend_p=*/0);
 	}
     }
-  /* Enter the DECL into the scope of the class.  */
-  else if (pushdecl_class_level (decl))
+  /* Enter the DECL into the scope of the class, if the class
+     isn't a closure (whose fields are supposed to be unnamed).  */
+  else if (CLASSTYPE_LAMBDA_EXPR (current_class_type)
+	   || pushdecl_class_level (decl))
     {
       if (TREE_CODE (decl) == USING_DECL)
 	{
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-names1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-names1.C
new file mode 100644
index 0000000..df2b037
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-names1.C
@@ -0,0 +1,9 @@ 
+// PR c++/56710
+// { dg-options "-std=c++11 -Wall" }
+
+int main()
+{
+    int t = 0;
+    return [&]() -> int {int __t; __t = t; return __t; }();
+    return [&t]() -> int {int __t; __t = t; return __t; }();
+}

commit db4f00892384f76f442401984007eb2a0b476eb2
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 27 15:31:09 2013 -0400

    	* name-lookup.c (pushdecl_maybe_friend_1): Use
    	nonlambda_method_basetype and current_nonlambda_class_type.

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 0a0915a..e2ef75b 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -1163,8 +1163,8 @@  pushdecl_maybe_friend_1 (tree x, bool is_friend)
 	    {
 	      tree member;
 
-	      if (current_class_ptr)
-		member = lookup_member (current_class_type,
+	      if (nonlambda_method_basetype ())
+		member = lookup_member (current_nonlambda_class_type (),
 					name,
 					/*protect=*/0,
 					/*want_type=*/false,
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow2.C
new file mode 100644
index 0000000..8237a81
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow2.C
@@ -0,0 +1,10 @@ 
+// { dg-options "-std=c++11 -Wshadow" }
+
+struct A
+{
+  int i;
+  void f()
+  {
+    [=]{ int i; };		// { dg-warning "shadows" }
+  }
+};