Patchwork C++ PATCH for c++/55149 (VLA lambda capture)

login
register
mail settings
Submitter Jason Merrill
Date May 10, 2013, 2:17 p.m.
Message ID <518D0181.7000101@redhat.com>
Download mbox | patch
Permalink /patch/242994/
State New
Headers show

Comments

Jason Merrill - May 10, 2013, 2:17 p.m.
This bug talks about ICEs trying to capture a VLA by value.  We don't 
support that, but we can give a more helpful error.  In the comments 
Paolo also noticed that with the new support for capture by reference, 
we wrongly warn about returning a reference to the captured variable.

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

Patch

commit e88823b454079098df61d1701ac0c7b59a96b758
Author: Jason Merrill <jason@redhat.com>
Date:   Thu May 9 22:15:22 2013 -0400

    	PR c++/55149
    	* semantics.c (add_capture): Error rather than abort on copy
    	capture of VLA.
    	* typeck.c (maybe_warn_about_returning_address_of_local): Don't
    	warn about capture proxy.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 3e1a0bf..d0db10a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -9463,9 +9463,12 @@  add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
   type = lambda_capture_field_type (initializer, explicit_init_p);
   if (array_of_runtime_bound_p (type))
     {
+      if (!by_reference_p)
+	error ("array of runtime bound cannot be captured by copy, "
+	       "only by reference");
+
       /* For a VLA, we capture the address of the first element and the
 	 maximum index, and then reconstruct the VLA for the proxy.  */
-      gcc_assert (by_reference_p);
       tree elt = cp_build_array_ref (input_location, initializer,
 				     integer_zero_node, tf_warning_or_error);
       tree ctype = vla_capture_type (type);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index df5fc4a..b8ea555 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8140,6 +8140,7 @@  maybe_warn_about_returning_address_of_local (tree retval)
   if (DECL_P (whats_returned)
       && DECL_NAME (whats_returned)
       && DECL_FUNCTION_SCOPE_P (whats_returned)
+      && !is_capture_proxy (whats_returned)
       && !(TREE_STATIC (whats_returned)
 	   || TREE_PUBLIC (whats_returned)))
     {
diff --git a/gcc/testsuite/g++.dg/cpp1y/vla5.C b/gcc/testsuite/g++.dg/cpp1y/vla5.C
new file mode 100644
index 0000000..1f6da29
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/vla5.C
@@ -0,0 +1,8 @@ 
+// PR c++/55149
+// { dg-options -std=c++1y }
+
+void test(int n) {
+  int r[n];
+  [&r]() { return r + 0; };
+  [r]() { return r + 0; };	// { dg-error "captured by copy" }
+}