This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/70494 (ICE with lambda capture of array)


split_nonconstant_init_1 didn't know how to deal with arrays when building a cleanup. Rather than add that logic there, we can use cxx_maybe_build_cleanup, which does understand arrays, once we adjust it to handle non-VAR_DECLs.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 4c385da85bf8f9a1c0f26b25441aa2d182a2c02d
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Apr 14 23:58:39 2016 -0400

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

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 380bc79..38e6bd8 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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.  */
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index b921689..e59ad51 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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
index 0000000..d0063e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array2.C
@@ -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]{};
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]