Patchwork C++ PATCH for c++/56901 (lambda, auto)

login
register
mail settings
Submitter Jason Merrill
Date April 11, 2013, 4:47 p.m.
Message ID <5166E93D.3040905@redhat.com>
Download mbox | patch
Permalink /patch/235831/
State New
Headers show

Comments

Jason Merrill - April 11, 2013, 4:47 p.m.
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.

Patch

commit 64b11356a1c53c61f2557fdbc495a1c610ef0417
Author: Jason Merrill <jason@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>();
+}