[gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] c++: Fix sizeof VLA lambda capture.

Martin Liska marxin@gcc.gnu.org
Mon Mar 30 10:42:29 GMT 2020


https://gcc.gnu.org/g:00a49cd840f60774b0e9e0109fb10559bc9a9194

commit 00a49cd840f60774b0e9e0109fb10559bc9a9194
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Jan 31 17:10:30 2020 -0500

    c++: Fix sizeof VLA lambda capture.
    
    sizeof a VLA type is not a constant in C or the GNU C++ extension, so we
    need to capture the VLA even in unevaluated context.  For PR60855 we stopped
    looking through a previous capture, but we also need to capture the first
    time the variable is mentioned.
    
            PR c++/86216
            * semantics.c (process_outer_var_ref): Capture VLAs even in
            unevaluated context.

Diff:
---
 gcc/cp/ChangeLog                                |  4 ++++
 gcc/cp/semantics.c                              | 11 +++++++++--
 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-vla5.C | 13 +++++++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cae1c918d30..999348d2e29 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
 2020-01-31  Jason Merrill  <jason@redhat.com>
 
+	PR c++/86216
+	* semantics.c (process_outer_var_ref): Capture VLAs even in
+	unevaluated context.
+
 	PR c++/14179
 	* decl.c (reshape_init_array_1): Reuse a single CONSTRUCTOR with
 	non-aggregate elements.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index a489e2cf399..90f1e18e48a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3524,8 +3524,15 @@ tree
 process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
 {
   if (cp_unevaluated_operand)
-    /* It's not a use (3.2) if we're in an unevaluated context.  */
-    return decl;
+    {
+      tree type = TREE_TYPE (decl);
+      if (!dependent_type_p (type)
+	  && variably_modified_type_p (type, NULL_TREE))
+	/* VLAs are used even in unevaluated context.  */;
+      else
+	/* It's not a use (3.2) if we're in an unevaluated context.  */
+	return decl;
+    }
   if (decl == error_mark_node)
     return decl;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-vla5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-vla5.C
new file mode 100644
index 00000000000..f3390b2d09f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-vla5.C
@@ -0,0 +1,13 @@
+// PR c++/86216
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -Wno-vla }
+
+template <typename T> void b(int n, T arg) {
+  int buffer[arg];
+  int buffer2[arg][arg];
+  [&] {
+    n = sizeof(buffer);
+    n = sizeof(buffer2);	// { dg-bogus "sorry" "" { xfail *-*-* } }
+  }();
+}
+int main() { b(2, 3); }


More information about the Gcc-cvs mailing list