re PR c++/70494 (Internal Compiler Error: Capturing an array of vectors in a lambda)
authorJason Merrill <jason@redhat.com>
Fri, 15 Apr 2016 04:02:49 +0000 (00:02 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 15 Apr 2016 04:02:49 +0000 (00:02 -0400)
PR c++/70494

* decl.c (cxx_maybe_build_cleanup): Handle non-decls.
* typeck2.c (split_nonconstant_init_1): Use it.

From-SVN: r235003

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

index 12900d3..2c51810 100644 (file)
@@ -1,5 +1,9 @@
 2016-04-14  Jason Merrill  <jason@redhat.com>
 
+       PR c++/70494
+       * decl.c (cxx_maybe_build_cleanup): Handle non-decls.
+       * typeck2.c (split_nonconstant_init_1): Use it.
+
        PR c++/70528
        * class.c (type_has_constexpr_default_constructor): Return true
        for an implicitly declared constructor.
index 380bc79..38e6bd8 100644 (file)
@@ -15021,7 +15021,8 @@ complete_vars (tree type)
 
 /* If DECL is of a type which needs a cleanup, build and return an
    expression to perform that cleanup here.  Return NULL_TREE if no
-   cleanup need be done.  */
+   cleanup need be done.  DECL can also be a _REF when called from
+   split_nonconstant_init_1.  */
 
 tree
 cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
@@ -15039,7 +15040,10 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
   /* Handle "__attribute__((cleanup))".  We run the cleanup function
      before the destructor since the destructor is what actually
      terminates the lifetime of the object.  */
-  attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
+  if (DECL_P (decl))
+    attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
+  else
+    attr = NULL_TREE;
   if (attr)
     {
       tree id;
@@ -15098,6 +15102,7 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
   protected_set_expr_location (cleanup, UNKNOWN_LOCATION);
 
   if (cleanup
+      && DECL_P (decl)
       && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (TREE_TYPE (decl)))
       /* Treat objects with destructors as used; the destructor may do
         something substantive.  */
index b921689..e59ad51 100644 (file)
@@ -688,14 +688,9 @@ split_nonconstant_init_1 (tree dest, tree init)
                  code = build_stmt (input_location, EXPR_STMT, code);
                  code = maybe_cleanup_point_expr_void (code);
                  add_stmt (code);
-                 if (type_build_dtor_call (inner_type))
-                   {
-                     code = (build_special_member_call
-                             (sub, complete_dtor_identifier, NULL, inner_type,
-                              LOOKUP_NORMAL, tf_warning_or_error));
-                     if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
-                       finish_eh_cleanup (code);
-                   }
+                 if (tree cleanup
+                     = cxx_maybe_build_cleanup (sub, tf_warning_or_error))
+                   finish_eh_cleanup (cleanup);
                }
 
              num_split_elts++;
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array2.C
new file mode 100644 (file)
index 0000000..d0063e1
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/70494
+// { dg-do compile { target c++11 } }
+
+struct A { ~A(); };
+
+int main()
+{
+  A v[] = { A(), A() };
+  auto lambda = [v]{};
+}