From patchwork Sat Feb 5 05:57:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 50824 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 226733858D28 for ; Sat, 5 Feb 2022 05:57:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 226733858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1644040675; bh=belwMOR5EgJsRiUnyo7rAX3keSOjVe0O6DoG1UZ4prE=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=qbEqqfiSlZ3ad46EowqgHRMxtxQUSLWqLKdgvNlM4jNsHLWRN1HxmsBB77Y0UO//8 IMUkyKI5Z0gA/RECcwS5ct0jaaI5AXGRVM6IjfKB4P+q8BDPGp8QM5881KXBXf8HOH hHHNqRuG+Uo2gWwwnMvdPpvLOJ+8ODROQDsgB3pI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 99E813858D20 for ; Sat, 5 Feb 2022 05:57:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 99E813858D20 Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-628-0DuFkT25PGum_BAhd_uNbA-1; Sat, 05 Feb 2022 00:57:20 -0500 X-MC-Unique: 0DuFkT25PGum_BAhd_uNbA-1 Received: by mail-qt1-f197.google.com with SMTP id c20-20020ac84e14000000b002d198444921so6385139qtw.23 for ; Fri, 04 Feb 2022 21:57:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=belwMOR5EgJsRiUnyo7rAX3keSOjVe0O6DoG1UZ4prE=; b=ODcW3yCiBafwSDgqyoP0SCJFC1NwI2aktG4dIUTNEO+h+cCnyNKGElgCuJGkwEyaad Jlz9xGNv/Qdu1WvI1yiDSMHWmRZ4fDuDZbLg8Vlrt6OQyy/+41lz5V3JKRvguzDDL15u UMwEE+gQzIPVgCxxi3+Ajo+XwlOGl19CE8LxHMIqpd5Se2YaJY6oduKRcC5sV2B8hNZW z0s1SjHs41JW73MKz7pj7EJjInen2wKgSJpmjNE8fpJWosUP8kLYREUdAUAgUSmEian2 Me5cuJJORov8of/Fh5wdvh8XRKjde53SvBxDH3p2ltwXsQnaGEKOc6AAhqK8rYr+dxUN RU3w== X-Gm-Message-State: AOAM532jJk2LEbdkXqSrzyvoT/YHEQDXr0QTp9y8v9fU/hDDVc+SKOUk 4zB7Yjr6wijZ1cpFmC1gigz1P8qBi1QV9AtqC1LF8WrTbCBG+5Lle+OhJJCEX5d1nighpPdxZhf SL3HxHo5mnIca7H6WqjPfTYljJCxcSCtAhyBPKXhMVVFe83KudP7/wbTtEW1z2gO1vQ== X-Received: by 2002:a05:6214:2a4c:: with SMTP id jf12mr4351879qvb.10.1644040639141; Fri, 04 Feb 2022 21:57:19 -0800 (PST) X-Google-Smtp-Source: ABdhPJyL4EhFy5W4Mtv98201L3bZk60gG9xcdybMFARDjHyhJy2m9Xji5beCPl4OmPRY4YyN7kYlnA== X-Received: by 2002:a05:6214:2a4c:: with SMTP id jf12mr4351862qvb.10.1644040638453; Fri, 04 Feb 2022 21:57:18 -0800 (PST) Received: from barrymore.redhat.com (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id a141sm1998337qkc.73.2022.02.04.21.57.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Feb 2022 21:57:17 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: assignment, aggregate, array [PR104300] Date: Sat, 5 Feb 2022 00:57:15 -0500 Message-Id: <20220205055715.783566-1-jason@redhat.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jason Merrill via Gcc-patches From: Jason Merrill Reply-To: Jason Merrill Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" The PR92385 fix meant that we see more VEC_INIT_EXPR outside of INIT_EXPR; in such cases, we need to wrap them in TARGET_EXPR. I previously fixed that in build_array_copy; we also need it in process_init_constructor. After fixing that, I needed to adjust a few places to recognize the VEC_INIT_EXPR even inside a TARGET_EXPR. And prevent cp_fully_fold_init from lowering VEC_INIT_EXPR too soon. And handle COMPOUND_EXPR inside TARGET_EXPR better. Tested x86_64-pc-linux-gnu, applying to trunk. PR c++/104300 PR c++/92385 gcc/cp/ChangeLog: * cp-tree.h (get_vec_init_expr): New. (target_expr_needs_replace): New. * cp-gimplify.cc (cp_gimplify_init_expr): Use it. (struct cp_fold_data): New. (cp_fold_r): Only genericize inits at end of fn. (cp_fold_function): Here. (cp_fully_fold_init): Not here. * init.cc (build_vec_init): Use get_vec_init_expr. * tree.cc (build_vec_init_expr): Likewise. * typeck2.cc (split_nonconstant_init_1): Likewise. (process_init_constructor): Wrap VEC_INIT_EXPR in TARGET_EXPR. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array14.C: New test. --- gcc/cp/cp-tree.h | 27 +++++++++++++ gcc/cp/cp-gimplify.cc | 39 ++++++++++++------- gcc/cp/init.cc | 12 ++++-- gcc/cp/tree.cc | 4 +- gcc/cp/typeck2.cc | 9 ++++- gcc/testsuite/g++.dg/cpp0x/initlist-array14.C | 12 ++++++ 6 files changed, 82 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-array14.C base-commit: b523cae81c64c3557f3918ce01419242c4238009 prerequisite-patch-id: d7d6830edf31f488480912065efdaa76d040ef74 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b9eb71fbc3a..d71be0a5bc7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4201,6 +4201,18 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define VEC_INIT_EXPR_VALUE_INIT(NODE) \ TREE_LANG_FLAG_1 (VEC_INIT_EXPR_CHECK (NODE)) +/* If T is a VEC_INIT_EXPR, return it, possibly stripping a TARGET_EXPR + wrapper. Otherwise, return null. */ +inline tree +get_vec_init_expr (tree t) +{ + if (t && TREE_CODE (t) == TARGET_EXPR) + t = TARGET_EXPR_INITIAL (t); + if (t && TREE_CODE (t) == VEC_INIT_EXPR) + return t; + return NULL_TREE; +} + /* The condition under which this MUST_NOT_THROW_EXPR actually blocks exceptions. NULL_TREE means 'true'. */ #define MUST_NOT_THROW_COND(NODE) \ @@ -5361,6 +5373,21 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) && TARGET_EXPR_INITIAL (NODE) \ && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (NODE)))) +/* True if T is a TARGET_EXPR for which we'll need to replace_decl to use it as + an initializer. */ +inline bool +target_expr_needs_replace (tree t) +{ + if (!t || TREE_CODE (t) != TARGET_EXPR) + return false; + tree init = TARGET_EXPR_INITIAL (t); + if (!init || !VOID_TYPE_P (TREE_TYPE (init))) + return false; + while (TREE_CODE (init) == COMPOUND_EXPR) + init = TREE_OPERAND (init, 1); + return TREE_CODE (init) != AGGR_INIT_EXPR; +} + /* True if EXPR expresses direct-initialization of a TYPE. */ #define DIRECT_INIT_EXPR_P(TYPE,EXPR) \ (TREE_CODE (EXPR) == TARGET_EXPR && TREE_LANG_FLAG_2 (EXPR) \ diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index d1c653c5fda..d7323fb5c09 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -249,8 +249,7 @@ cp_gimplify_init_expr (tree *expr_p) if (TREE_CODE (from) == TARGET_EXPR) if (tree init = TARGET_EXPR_INITIAL (from)) { - if (VOID_TYPE_P (TREE_TYPE (init)) - && TREE_CODE (init) != AGGR_INIT_EXPR) + if (target_expr_needs_replace (from)) { /* If this was changed by cp_genericize_target_expr, we need to walk into it to replace uses of the slot. */ @@ -950,14 +949,23 @@ struct cp_genericize_data /* Perform any pre-gimplification folding of C++ front end trees to GENERIC. - Note: The folding of none-omp cases is something to move into + Note: The folding of non-omp cases is something to move into the middle-end. As for now we have most foldings only on GENERIC in fold-const, we need to perform this before transformation to GIMPLE-form. */ -static tree -cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) +struct cp_fold_data { + hash_set pset; + bool genericize; // called from cp_fold_function? + + cp_fold_data (bool g): genericize (g) {} +}; + +static tree +cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) +{ + cp_fold_data *data = (cp_fold_data*)data_; tree stmt = *stmt_p; enum tree_code code = TREE_CODE (stmt); @@ -967,7 +975,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) if (TREE_CODE (PTRMEM_CST_MEMBER (stmt)) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (stmt))) { - if (!((hash_set *) data)->add (stmt)) + if (!data->pset.add (stmt)) error_at (PTRMEM_CST_LOCATION (stmt), "taking address of an immediate function %qD", PTRMEM_CST_MEMBER (stmt)); @@ -1001,7 +1009,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) *stmt_p = stmt = cp_fold (*stmt_p); - if (((hash_set *) data)->add (stmt)) + if (data->pset.add (stmt)) { /* Don't walk subtrees of stmts we've already walked once, otherwise we can have exponential complexity with e.g. lots of nested @@ -1075,12 +1083,17 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) } break; + /* These are only for genericize time; they're here rather than in + cp_genericize to avoid problems with the invisible reference + transition. */ case INIT_EXPR: - cp_genericize_init_expr (stmt_p); + if (data->genericize) + cp_genericize_init_expr (stmt_p); break; case TARGET_EXPR: - cp_genericize_target_expr (stmt_p); + if (data->genericize) + cp_genericize_target_expr (stmt_p); break; default: @@ -1096,8 +1109,8 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) void cp_fold_function (tree fndecl) { - hash_set pset; - cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &pset, NULL); + cp_fold_data data (/*genericize*/true); + cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL); } /* Turn SPACESHIP_EXPR EXPR into GENERIC. */ @@ -2358,8 +2371,8 @@ cp_fully_fold_init (tree x) if (processing_template_decl) return x; x = cp_fully_fold (x); - hash_set pset; - cp_walk_tree (&x, cp_fold_r, &pset, NULL); + cp_fold_data data (/*genericize*/false); + cp_walk_tree (&x, cp_fold_r, &data, NULL); return x; } diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 1f047831b6d..fcb255f1ac7 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -4368,8 +4368,8 @@ build_vec_init (tree base, tree maxindex, tree init, && from_array != 2) init = TARGET_EXPR_INITIAL (init); - if (init && TREE_CODE (init) == VEC_INIT_EXPR) - init = VEC_INIT_EXPR_INIT (init); + if (tree vi = get_vec_init_expr (init)) + init = VEC_INIT_EXPR_INIT (vi); bool direct_init = false; if (from_array && init && BRACE_ENCLOSED_INITIALIZER_P (init) @@ -4581,10 +4581,14 @@ build_vec_init (tree base, tree maxindex, tree init, num_initialized_elts++; + /* We need to see sub-array TARGET_EXPR before cp_fold_r so we can + handle cleanup flags properly. */ + gcc_checking_assert (!target_expr_needs_replace (elt)); + if (digested) one_init = build2 (INIT_EXPR, type, baseref, elt); - else if (TREE_CODE (elt) == VEC_INIT_EXPR) - one_init = expand_vec_init_expr (baseref, elt, complain, flags); + else if (tree vi = get_vec_init_expr (elt)) + one_init = expand_vec_init_expr (baseref, vi, complain, flags); else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE) one_init = build_aggr_init (baseref, elt, 0, complain); else diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 2d8f2c551c0..6e9be713c51 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -785,8 +785,8 @@ build_vec_init_elt (tree type, tree init, tsubst_flags_t complain) tree build_vec_init_expr (tree type, tree init, tsubst_flags_t complain) { - if (init && TREE_CODE (init) == VEC_INIT_EXPR) - return init; + if (tree vi = get_vec_init_expr (init)) + return vi; tree elt_init; if (init && TREE_CODE (init) == CONSTRUCTOR diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc index f439dd54866..4015bd53257 100644 --- a/gcc/cp/typeck2.cc +++ b/gcc/cp/typeck2.cc @@ -548,6 +548,10 @@ split_nonconstant_init_1 (tree dest, tree init, bool last, bool elt_last = last && idx == CONSTRUCTOR_NELTS (init) - 1; + /* We need to see sub-array TARGET_EXPR before cp_fold_r so we can + handle cleanup flags properly. */ + gcc_checking_assert (!target_expr_needs_replace (value)); + if (TREE_CODE (value) == CONSTRUCTOR) { if (!split_nonconstant_init_1 (sub, value, elt_last, flags) @@ -574,9 +578,9 @@ split_nonconstant_init_1 (tree dest, tree init, bool last, num_split_elts++; } } - else if (TREE_CODE (value) == VEC_INIT_EXPR) + else if (tree vi = get_vec_init_expr (value)) { - add_stmt (expand_vec_init_expr (sub, value, tf_warning_or_error, + add_stmt (expand_vec_init_expr (sub, vi, tf_warning_or_error, flags)); /* Mark element for removal. */ @@ -1925,6 +1929,7 @@ process_init_constructor (tree type, tree init, int nested, int flags, initializer-clause until later so we can use a loop. */ TREE_TYPE (init) = init_list_type_node; init = build_vec_init_expr (type, init, complain); + init = get_target_expr (init); } return init; } diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array14.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array14.C new file mode 100644 index 00000000000..baa4afc91fd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array14.C @@ -0,0 +1,12 @@ +// PR c++/104300 +// { dg-do compile { target c++11 } } + +struct ss { + char r; + ss(); +}; +struct a { + ss e[6]; +}; +a vv; +void ff() { vv = {}; }