public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-5403] c++: nested lambda capturing a capture proxy [PR94376]
@ 2021-11-19 13:54 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2021-11-19 13:54 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:fd740165e54151ea794fca34904f5c2e2ea1dcda

commit r12-5403-gfd740165e54151ea794fca34904f5c2e2ea1dcda
Author: Patrick Palka <ppalka@redhat.com>
Date:   Fri Nov 19 08:54:25 2021 -0500

    c++: nested lambda capturing a capture proxy [PR94376]
    
    Here when determining the type of the FIELD_DECL for the by-value capture
    of 'i' in the inner lambda, we incorrectly give it the type const int
    instead of int since the effective initializer is the proxy for the outer
    capture, and this proxy is const since the outer lambda is non-mutable.
    
    This patch fixes this by making lambda_capture_field_type handle
    by-value capturing of capture proxies specially, namely we instead
    consider the type of their FIELD_DECL which unlike the proxy has the
    true cv-quals of the captured entity.
    
            PR c++/94376
    
    gcc/cp/ChangeLog:
    
            * lambda.c (lambda_capture_field_type): Simplify by handling the
            is_this case first.  When capturing by-value a capture proxy,
            consider the type of the corresponding field instead.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/lambda/lambda-nested9.C: New test.

Diff:
---
 gcc/cp/lambda.c                                    | 19 +++++++---
 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C | 41 ++++++++++++++++++++++
 2 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index f68c68ca16e..c39a2bca416 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -195,7 +195,9 @@ lambda_capture_field_type (tree expr, bool explicit_init_p,
   tree type;
   bool is_this = is_this_parameter (tree_strip_nop_conversions (expr));
 
-  if (!is_this && explicit_init_p)
+  if (is_this)
+    type = TREE_TYPE (expr);
+  else if (explicit_init_p)
     {
       tree auto_node = make_auto ();
       
@@ -209,7 +211,7 @@ lambda_capture_field_type (tree expr, bool explicit_init_p,
       else
 	type = do_auto_deduction (type, expr, auto_node);
     }
-  else if (!is_this && type_dependent_expression_p (expr))
+  else if (type_dependent_expression_p (expr))
     {
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
@@ -219,10 +221,19 @@ lambda_capture_field_type (tree expr, bool explicit_init_p,
     }
   else
     {
+      if (!by_reference_p && is_capture_proxy (expr))
+	{
+	  /* When capturing by-value another capture proxy from an enclosing
+	     lambda, consider the type of the corresponding field instead,
+	     as the proxy may be additionally const-qualifed if the enclosing
+	     lambda is non-mutable (PR94376).  */
+	  gcc_assert (TREE_CODE (DECL_VALUE_EXPR (expr)) == COMPONENT_REF);
+	  expr = TREE_OPERAND (DECL_VALUE_EXPR (expr), 1);
+	}
+
       type = non_reference (unlowered_expr_type (expr));
 
-      if (!is_this
-	  && (by_reference_p || TREE_CODE (type) == FUNCTION_TYPE))
+      if (by_reference_p || TREE_CODE (type) == FUNCTION_TYPE)
 	type = build_reference_type (type);
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C
new file mode 100644
index 00000000000..ff7da3b0ce1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested9.C
@@ -0,0 +1,41 @@
+// PR c++/94376
+// { dg-do compile { target c++11 } }
+
+int main() {
+  // We used to incorrectly reject the first two cases.
+  int i = 0;
+  [=] () {
+    [=] () mutable {
+      ++i;
+    };
+  };
+
+#if __cpp_init_captures
+  [j=0] () {
+    [=] () mutable {
+      ++j;
+    };
+  };
+#endif
+
+  [=] () {
+    [&] () mutable {
+      ++i; // { dg-error "read-only" }
+    };
+  };
+
+  const int j = 0;
+  [=] () {
+    [=] () mutable {
+      ++j; // { dg-error "read-only" }
+    };
+  };
+
+#if __cpp_init_captures
+  [j=0] () {
+    [&] () mutable {
+      ++j; // { dg-error "read-only" }
+    };
+  };
+#endif
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-11-19 13:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-19 13:54 [gcc r12-5403] c++: nested lambda capturing a capture proxy [PR94376] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).