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.
commit 03426fb7d994c8eb6bf7f1097c45f6079e8227d5
Author: Jason Merrill <ja...@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 <ja...@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" }
+ }
+};