c++: Fix sizeof VLA lambda capture.
authorJason Merrill <jason@redhat.com>
Fri, 31 Jan 2020 22:10:30 +0000 (17:10 -0500)
committerJason Merrill <jason@redhat.com>
Sat, 1 Feb 2020 00:06:37 +0000 (19:06 -0500)
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.

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-vla5.C [new file with mode: 0644]

index cae1c918d304f4a9e34b32680df7b8641fc5ba4a..999348d2e2904da7e6ef8a756122da6a85c4d84a 100644 (file)
@@ -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.
index a489e2cf3990331e5d18dba4f829041c9f8fde91..90f1e18e48a9ae3e266dd8a5f4748ce6229708cf 100644 (file)
@@ -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 (file)
index 0000000..f3390b2
--- /dev/null
@@ -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); }