My earlier patch to have lambda_capture_field_type and lambda_proxy_type just return the captured variable's type in more cases caused this regression; we were failing to recognize the case of an auto variable captured by reference. Fixed by stripping references.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 64b11356a1c53c61f2557fdbc495a1c610ef0417
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Apr 11 12:36:26 2013 -0400

    	PR c++/56901
    	* semantics.c (lambda_capture_field_type, lambda_proxy_type):
    	Strip references before checking WILDCARD_TYPE_P.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 3a558b0..0631833 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -9114,16 +9114,14 @@ lambda_function (tree lambda)
 tree
 lambda_capture_field_type (tree expr)
 {
-  tree type;
-  if (!TREE_TYPE (expr) || WILDCARD_TYPE_P (TREE_TYPE (expr)))
+  tree type = non_reference (unlowered_expr_type (expr));
+  if (!type || WILDCARD_TYPE_P (type))
     {
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
       DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
       SET_TYPE_STRUCTURAL_EQUALITY (type);
     }
-  else
-    type = non_reference (unlowered_expr_type (expr));
   return type;
 }
 
@@ -9324,7 +9322,7 @@ lambda_proxy_type (tree ref)
   if (REFERENCE_REF_P (ref))
     ref = TREE_OPERAND (ref, 0);
   type = TREE_TYPE (ref);
-  if (type && !WILDCARD_TYPE_P (type))
+  if (type && !WILDCARD_TYPE_P (non_reference (type)))
     return type;
   type = cxx_make_type (DECLTYPE_TYPE);
   DECLTYPE_TYPE_EXPR (type) = ref;
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto2.C
new file mode 100644
index 0000000..05fadf5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto2.C
@@ -0,0 +1,16 @@
+// PR c++/56901
+// { dg-require-effective-target c++11 }
+
+template <typename>
+void foo_impl()
+{
+  int data;
+  auto L = [&](){ return data; };
+  [&](){ L(); }();
+  [&L](){ L(); }();
+}
+
+void foo()
+{
+  foo_impl<int>();
+}

Reply via email to