From patchwork Mon May 2 21:58:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 93720 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 8D046B6F2B for ; Tue, 3 May 2011 07:58:54 +1000 (EST) Received: (qmail 4780 invoked by alias); 2 May 2011 21:58:53 -0000 Received: (qmail 4771 invoked by uid 22791); 2 May 2011 21:58:52 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_CX, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 02 May 2011 21:58:35 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p42LwZAp013076 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 2 May 2011 17:58:35 -0400 Received: from [127.0.0.1] (ovpn-113-54.phx2.redhat.com [10.3.113.54]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p42LwYof016878 for ; Mon, 2 May 2011 17:58:34 -0400 Message-ID: <4DBF2909.4050207@redhat.com> Date: Mon, 02 May 2011 17:58:33 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.15) Gecko/20110307 Fedora/3.1.9-0.39.b3pre.fc14 Lightning/1.0b2 Thunderbird/3.1.9 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCHes relating to c++/48834, c++/40975 (array new) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org So, the problem in 48834 was that we had specified a particular target for the vec initialization, but it was getting clobbered by ending up on the rhs of an INIT_EXPR. So 48834.patch avoids that. But Diego doesn't think there was any real reason to abort on trying to copy a STATEMENT_LIST, so it seems to me that we could revert my earlier patch for 40975 and just add support for copying STATEMENT_LIST. So 40975-2.patch adds that support. I haven't attached a patch to revert my earlier 40975 patch. Some of the incidental changes from my earlier patch seem independently useful, so I'm reapplying those in vec-sfinae.patch. Tested x86_64-pc-linux-gnu, applying to trunk. Also applying 40975-2.patch to 4.4, 4.5 and 4.6; it doesn't fix the bug in 4.3 so I'm not applying it there. commit 41d391e1683e6ed7e28ad31f41732b3f4b691baa Author: Jason Merrill Date: Mon May 2 01:36:01 2011 -0400 PR c++/48834 * tree.c (build_vec_init_expr): Set TREE_SIDE_EFFECTS. Protect an explicit target. commit 98011319607130da27331a5f1b763ba8ce741734 Author: Jason Merrill Date: Mon May 2 16:02:29 2011 -0400 PR c++/40975 * tree-inline.c (copy_tree_r): Handle STATEMENT_LIST. diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 5da4a12..3777675 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4271,14 +4271,26 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) CONSTRUCTOR_ELTS (*tp)); *tp = new_tree; } + else if (code == STATEMENT_LIST) + { + /* We used to just abort on STATEMENT_LIST, but we can run into them + with statement-expressions (c++/40975). */ + tree new_list = alloc_stmt_list (); + tree_stmt_iterator i = tsi_start (*tp); + tree_stmt_iterator j = tsi_last (new_list); + for (; !tsi_end_p (i); tsi_next (&i)) + { + tree stmt = tsi_stmt (i); + tsi_link_after (&j, stmt, TSI_CONTINUE_LINKING); + } + *tp = new_list; + } else if (TREE_CODE_CLASS (code) == tcc_type) *walk_subtrees = 0; else if (TREE_CODE_CLASS (code) == tcc_declaration) *walk_subtrees = 0; else if (TREE_CODE_CLASS (code) == tcc_constant) *walk_subtrees = 0; - else - gcc_assert (code != STATEMENT_LIST); return NULL_TREE; } commit 6f60af2d7324b81f4b524c34c321280e4874c2ee Author: Jason Merrill Date: Mon May 2 17:02:10 2011 -0400 * tree.c (build_vec_init_expr): Take complain parm. (build_vec_init_elt): Likewise. Free arg vector. (diagnose_non_constexpr_vec_init, build_array_copy): Adjust. * cp-tree.h (VEC_INIT_EXPR_SLOT): Use VEC_INIT_EXPR_CHECK. (VEC_INIT_EXPR_INIT): Likewise. Adjust build_vec_init_expr declaration. * init.c (perform_member_init): Adjust. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9bad404..961581e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2896,8 +2896,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) (arg) = next_aggr_init_expr_arg (&(iter))) /* VEC_INIT_EXPR accessors. */ -#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (NODE, 0) -#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (NODE, 1) +#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 0) +#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 1) /* Indicates that a VEC_INIT_EXPR is a potential constant expression. Only set when the current function is constexpr. */ @@ -5420,7 +5420,7 @@ extern tree get_target_expr_sfinae (tree, tsubst_flags_t); extern tree build_cplus_array_type (tree, tree); extern tree build_array_of_n_type (tree, int); extern tree build_array_copy (tree); -extern tree build_vec_init_expr (tree, tree); +extern tree build_vec_init_expr (tree, tree, tsubst_flags_t); extern void diagnose_non_constexpr_vec_init (tree); extern tree hash_tree_cons (tree, tree, tree); extern tree hash_tree_chain (tree, tree); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 50dbcc9..7a7379e 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -506,7 +506,7 @@ perform_member_init (tree member, tree init) /* mem() means value-initialization. */ if (TREE_CODE (type) == ARRAY_TYPE) { - init = build_vec_init_expr (type, init); + init = build_vec_init_expr (type, init, tf_warning_or_error); init = build2 (INIT_EXPR, type, decl, init); finish_expr_stmt (init); } @@ -543,7 +543,7 @@ perform_member_init (tree member, tree init) || same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))) { - init = build_vec_init_expr (type, init); + init = build_vec_init_expr (type, init, tf_warning_or_error); init = build2 (INIT_EXPR, type, decl, init); finish_expr_stmt (init); } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index dfd11ad..0f2f86c 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -475,7 +475,7 @@ build_cplus_new (tree type, tree init, tsubst_flags_t complain) another array to copy. */ static tree -build_vec_init_elt (tree type, tree init) +build_vec_init_elt (tree type, tree init, tsubst_flags_t complain) { tree inner_type = strip_array_types (type); VEC(tree,gc) *argvec; @@ -485,7 +485,7 @@ build_vec_init_elt (tree type, tree init) /* No interesting initialization to do. */ return integer_zero_node; else if (init == void_type_node) - return build_value_init (inner_type, tf_warning_or_error); + return build_value_init (inner_type, complain); gcc_assert (init == NULL_TREE || (same_type_ignoring_top_level_qualifiers_p @@ -499,9 +499,12 @@ build_vec_init_elt (tree type, tree init) dummy = move (dummy); VEC_quick_push (tree, argvec, dummy); } - return build_special_member_call (NULL_TREE, complete_ctor_identifier, + init = build_special_member_call (NULL_TREE, complete_ctor_identifier, &argvec, inner_type, LOOKUP_NORMAL, - tf_warning_or_error); + complain); + release_tree_vector (argvec); + + return init; } /* Return a TARGET_EXPR which expresses the initialization of an array to @@ -509,11 +512,11 @@ build_vec_init_elt (tree type, tree init) from another array of the same type. */ tree -build_vec_init_expr (tree type, tree init) +build_vec_init_expr (tree type, tree init, tsubst_flags_t complain) { tree slot; bool value_init = false; - tree elt_init = build_vec_init_elt (type, init); + tree elt_init = build_vec_init_elt (type, init, complain); if (init == void_type_node) { @@ -550,14 +553,14 @@ diagnose_non_constexpr_vec_init (tree expr) else init = VEC_INIT_EXPR_INIT (expr); - elt_init = build_vec_init_elt (type, init); + elt_init = build_vec_init_elt (type, init, tf_warning_or_error); require_potential_constant_expression (elt_init); } tree build_array_copy (tree init) { - return build_vec_init_expr (TREE_TYPE (init), init); + return build_vec_init_expr (TREE_TYPE (init), init, tf_warning_or_error); } /* Build a TARGET_EXPR using INIT to initialize a new temporary of the diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2eaa1db..fff3fbf 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -564,6 +564,7 @@ build_vec_init_expr (tree target, tree init, tree nelts, elt_init = build_vec_init_elt (type, init, complain); init = build3 (VEC_INIT_EXPR, type, slot, init, nelts); + TREE_SIDE_EFFECTS (init) = true; SET_EXPR_LOCATION (init, input_location); if (cxx_dialect >= cxx0x @@ -571,7 +572,11 @@ build_vec_init_expr (tree target, tree init, tree nelts, VEC_INIT_EXPR_IS_CONSTEXPR (init) = true; VEC_INIT_EXPR_VALUE_INIT (init) = value_init; - if (slot != target) + if (slot == target) + /* If we specified what array we're initializing, make sure + we don't override that in cp_gimplify_init_expr. */ + init = cp_build_compound_expr (init, slot, complain); + else { init = build_target_expr (slot, init, complain); TARGET_EXPR_IMPLICIT_P (init) = 1; diff --git a/gcc/testsuite/g++.dg/init/new31.C b/gcc/testsuite/g++.dg/init/new31.C new file mode 100644 index 0000000..33c94aa --- /dev/null +++ b/gcc/testsuite/g++.dg/init/new31.C @@ -0,0 +1,18 @@ +// PR c++/48834 +// { dg-options -Wuninitialized } +// { dg-do run } + +struct S +{ + S ():i (0) + { + } + int i; +}; + +int +main () +{ + S *s = new S[2]; + return 0; +}