]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/90732 - ICE with VLA capture and generic lambda.
authorJason Merrill <jason@redhat.com>
Mon, 2 Mar 2020 19:42:47 +0000 (14:42 -0500)
committerJason Merrill <jason@redhat.com>
Mon, 2 Mar 2020 20:49:57 +0000 (15:49 -0500)
We were failing to handle VLA capture in tsubst_lambda_expr; initially
building a DECLTYPE_TYPE for the capture and then tsubsting it doesn't give
the special VLA handling.  So with this patch we call add_capture again for
VLAs.

gcc/cp/ChangeLog
2020-03-02  Jason Merrill  <jason@redhat.com>

PR c++/90732 - ICE with VLA capture and generic lambda.
* pt.c (tsubst_lambda_expr): Repeat add_capture for VLAs.

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1y/lambda-vla1.C [new file with mode: 0644]

index 80971a9d74e46b1d7feab867960ac32170398baf..2b134eed5723307aeb6cdef33f9b2588fac5ef33 100644 (file)
@@ -1,3 +1,8 @@
+2020-03-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/90732 - ICE with VLA capture and generic lambda.
+       * pt.c (tsubst_lambda_expr): Repeat add_capture for VLAs.
+
 2020-03-02  Jason Merrill  <jason@redhat.com>
 
        PR c++/90333
index c7ca7e419ea074d0e8c7aff2ed2487ead5d0a438..f233e78cc451b4490be8296939d365a0658691a1 100644 (file)
@@ -18130,6 +18130,36 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        cap = TREE_CHAIN (cap))
     {
       tree ofield = TREE_PURPOSE (cap);
+      tree init = TREE_VALUE (cap);
+      if (PACK_EXPANSION_P (init))
+       init = tsubst_pack_expansion (init, args, complain, in_decl);
+      else
+       init = tsubst_copy_and_build (init, args, complain, in_decl,
+                                     /*fn*/false, /*constexpr*/false);
+
+      if (init == error_mark_node)
+       return error_mark_node;
+
+      if (init && TREE_CODE (init) == TREE_LIST)
+       init = build_x_compound_expr_from_list (init, ELK_INIT, complain);
+
+      if (!processing_template_decl
+         && init && TREE_CODE (init) != TREE_VEC
+         && variably_modified_type_p (TREE_TYPE (init), NULL_TREE))
+       {
+         /* For a VLA, simply tsubsting the field type won't work, we need to
+            go through add_capture again.  XXX do we want to do this for all
+            captures?  */
+         tree name = (get_identifier
+                      (IDENTIFIER_POINTER (DECL_NAME (ofield)) + 2));
+         tree ftype = TREE_TYPE (ofield);
+         bool by_ref = (TYPE_REF_P (ftype)
+                        || (TREE_CODE (ftype) == DECLTYPE_TYPE
+                            && DECLTYPE_FOR_REF_CAPTURE (ftype)));
+         add_capture (r, name, init, by_ref, !DECL_NORMAL_CAPTURE_P (ofield));
+         continue;
+       }
+
       if (PACK_EXPANSION_P (ofield))
        ofield = PACK_EXPANSION_PATTERN (ofield);
       tree field = tsubst_decl (ofield, args, complain);
@@ -18144,13 +18174,6 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       if (field == error_mark_node)
        return error_mark_node;
 
-      tree init = TREE_VALUE (cap);
-      if (PACK_EXPANSION_P (init))
-       init = tsubst_pack_expansion (init, args, complain, in_decl);
-      else
-       init = tsubst_copy_and_build (init, args, complain, in_decl,
-                                     /*fn*/false, /*constexpr*/false);
-
       if (TREE_CODE (field) == TREE_VEC)
        {
          int len = TREE_VEC_LENGTH (field);
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-vla1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-vla1.C
new file mode 100644 (file)
index 0000000..c9025c7
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/90732
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-Wno-vla" }
+
+/*const*/ int SIZE = 100;
+
+template<typename T>
+int foo(T t) {
+  char buf[SIZE] = { 24 };
+  return [&buf](auto x){ return buf[x]; }(t);
+}
+
+int main() {
+  if (foo(0) != 24)
+    __builtin_abort();
+}