From: Jason Merrill Date: Fri, 15 Apr 2016 04:02:49 +0000 (-0400) Subject: re PR c++/70494 (Internal Compiler Error: Capturing an array of vectors in a lambda) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8e718ecbb0ded9686113e64c9241c083b7afc620;p=gcc.git re PR c++/70494 (Internal Compiler Error: Capturing an array of vectors in a lambda) PR c++/70494 * decl.c (cxx_maybe_build_cleanup): Handle non-decls. * typeck2.c (split_nonconstant_init_1): Use it. From-SVN: r235003 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 12900d3cd45..2c51810d7db 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-04-14 Jason Merrill + 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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 380bc79ea53..38e6bd83a2a 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 b921689808a..e59ad51c3bd 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 00000000000..d0063e11cbf --- /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]{}; +}