From patchwork Thu Mar 9 21:26:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 67117 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp527602wrd; Thu, 9 Mar 2023 13:27:20 -0800 (PST) X-Google-Smtp-Source: AK7set/tzADf551FhjeNChAhZDTV4rGAM5d9Dt4OSlJ0H33EL5RwWJQdfUCUvpuHEAm/bu7AzwkM X-Received: by 2002:a05:6402:35a:b0:4ab:4dc6:6f8c with SMTP id r26-20020a056402035a00b004ab4dc66f8cmr22987731edw.4.1678397240409; Thu, 09 Mar 2023 13:27:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678397240; cv=none; d=google.com; s=arc-20160816; b=GWBhRNdAl3o74nCIgfaKmNRxI83wGvACRSpKdZ7sU73WrYp2+bwo6vbstzM6OT05PD lH7NrMwc7eiDYpeFWsR1HdB3s33xVnt3XtS3r7RRoRJh4zosATBW01GhGrU46vITr47u LGtsiYnJ4lTUcyQFUgULkJuzq3zRzBg1HJUmyWAHlZhtmEmrILW3/iUPIoR9iKvtORME EvfkUb+D6PMvuZkhQ5z3K5lYziWvlSCuKFHj7IwIEXEqtYfKXmKm82/31cyugZs0n1jR gsj3jJIbnPsY+u9vZxkdhVcyyAqbm49N5nXSqEH2XciCP7Tbo6dk+0FO7Y/x1V7mGWjC 8ZYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=rrF5StGa227v4I3q4AoKclqumeRTuUYgquOAxvwu8OQ=; b=gNnVN7lHebjTd7hTDV3l2gloBunOaKQjbEohcJxiK7scVriYYE38BtfAr2WZ87M66n wWNlWQn+vlOM5RluV2XfeY8WiHVpccq9MD4ANp92VWN6T9Pz935OBJJDcbZV/V46R4LE nBx7BfFsmEMxG9BoMQgASpQJwB32QRjtC0ndAoc9O92BR0+HAVUS8CbiSJYUuuxhZwum RUPgZbMGg0GWv9EjSMU1xg62aynTGUpElkOnlMZbXNGSlGs+RcxXEkqKRSm72B97YAdF l6k8xecSTkapdY+toXxbXEopSucpGztg9d8qmoaV+jMuqqFEnLcAlC5eKZV+/8Ih5skk HxlA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=EbFTkZtc; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id e14-20020a50ec8e000000b004ab092142e1si478777edr.406.2023.03.09.13.27.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Mar 2023 13:27:20 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=EbFTkZtc; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 67D1D3850425 for ; Thu, 9 Mar 2023 21:27:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 67D1D3850425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1678397231; bh=rrF5StGa227v4I3q4AoKclqumeRTuUYgquOAxvwu8OQ=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=EbFTkZtcTqcWgU9fjbnH8UnXmK0FW2C8mKR+CeQ9uLSGHsBPhK28X3BIOV+GhsO6I m37NY2LMZ72spwX2lHNDthqH19LxCvEN7lnTskcuFzCgX3rmeH0CfRVG/3ucvrJp2Q rd9y3+YxsonRhl0QZGhOvSiCtf4m8Uox+1LgNc7Y= 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 45EB63858C60 for ; Thu, 9 Mar 2023 21:26:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 45EB63858C60 Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-202-ZJ1hawd4PvKeYMVhfd51Cw-1; Thu, 09 Mar 2023 16:26:24 -0500 X-MC-Unique: ZJ1hawd4PvKeYMVhfd51Cw-1 Received: by mail-qt1-f200.google.com with SMTP id br8-20020a05622a1e0800b003c0189c37e1so1796369qtb.18 for ; Thu, 09 Mar 2023 13:26:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678397184; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rrF5StGa227v4I3q4AoKclqumeRTuUYgquOAxvwu8OQ=; b=WdNPrQqvyEjRDRIzGg6uQtZmx8APM3X/WIAkbq0NnX4GDq0pF+951bSGvVt6jW6/Sv GAA+j71C4Y5IYv6gE+kfQPR4ks8+GaTarKS7Al9QtaK/rT6pS9OLt1l7w1eaUPFoN5Z0 yyeNcNGado+MpdtJvYdvOK7uumwHxXxX/EleS/9+LQkGaMsvQOxBVRDWI0zfWbDtnfiv K35zfnWgRHisOIJ163AB8IaoFlGIXTmEXv/mJvStzIZHeqWSg3Eb4aRUrQqHUNkCcw+3 pGOioFR1s6jz8TBoZqjNZOV0kM2SsRsI9rDQhAAmCwGJwWzfJkVx8ufeahe1Mls9s9qd o6jw== X-Gm-Message-State: AO0yUKU9kbDPZ1m0sqeO1jjQRm7CkAbEBId4ZvRVLJpLW40mqUKV9aRv TER/HludqKPwOdIbiSSI31ZmdhRNgYYmqej/6o5clEBChixWpYxH5iwfcPrhZim1cRXRmJTi1ze KYVAtfUlMYuidpYjV2Ay20nmR2kw7KOvWvaj2Emh2KfxYo/A9ELeegGVGoOGodt2Xsrd59jDoag == X-Received: by 2002:a05:622a:648:b0:3bf:d988:f8e3 with SMTP id a8-20020a05622a064800b003bfd988f8e3mr38574685qtb.38.1678397184151; Thu, 09 Mar 2023 13:26:24 -0800 (PST) X-Received: by 2002:a05:622a:648:b0:3bf:d988:f8e3 with SMTP id a8-20020a05622a064800b003bfd988f8e3mr38574647qtb.38.1678397183576; Thu, 09 Mar 2023 13:26:23 -0800 (PST) Received: from jason.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 j128-20020a378786000000b0071ddbe8fe23sm17248qkd.24.2023.03.09.13.26.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Mar 2023 13:26:22 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: allocator temps in list of arrays [PR108773] Date: Thu, 9 Mar 2023 16:26:19 -0500 Message-Id: <20230309212619.2329010-1-jason@redhat.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.6 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_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1759927065188243015?= X-GMAIL-MSGID: =?utf-8?q?1759927065188243015?= Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< -- The optimization to reuse the same allocator temporary for all string constructor calls was breaking on this testcase, because the temps were already in the argument to build_vec_init, and replacing them with references to one slot got confused with calls at multiple levels (for the initializer_list backing array, and then again for the array member of the std::array). Fixed by reusing the whole TARGET_EXPR instead of pulling out the slot; gimplification ensures that it's only initialized once. I also moved the check for initializing a std:: class down into the tree walk, and handle multiple temps within a single array element initialization. PR c++/108773 gcc/cp/ChangeLog: * init.cc (find_allocator_temps_r): New. (combine_allocator_temps): Replace find_allocator_temp. (build_vec_init): Adjust. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array18.C: New test. * g++.dg/cpp0x/initlist-array19.C: New test. --- gcc/cp/init.cc | 78 ++++++++++++++----- gcc/testsuite/g++.dg/cpp0x/initlist-array18.C | 30 +++++++ gcc/testsuite/g++.dg/cpp0x/initlist-array19.C | 23 ++++++ 3 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-array18.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-array19.C base-commit: afe1f0c251d0429069c2414d4f3f14042efc174f diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 52e96fbe590..1b7d3d8fe3e 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -4330,8 +4330,54 @@ find_temps_r (tree *tp, int *walk_subtrees, void *data) return NULL_TREE; } +/* walk_tree callback to collect temporaries in an expression that + are allocator arguments to standard library classes. */ + +static tree +find_allocator_temps_r (tree *tp, int *walk_subtrees, void *data) +{ + vec &temps = *static_cast *>(data); + tree t = *tp; + if (TYPE_P (t)) + { + *walk_subtrees = 0; + return NULL_TREE; + } + + /* If this is a call to a constructor for a std:: class, look for + a reference-to-allocator argument. */ + tree fn = cp_get_callee_fndecl_nofold (t); + if (fn && DECL_CONSTRUCTOR_P (fn) + && decl_in_std_namespace_p (TYPE_NAME (DECL_CONTEXT (fn)))) + { + int nargs = call_expr_nargs (t); + for (int i = 1; i < nargs; ++i) + { + tree arg = get_nth_callarg (t, i); + tree atype = TREE_TYPE (arg); + if (TREE_CODE (atype) == REFERENCE_TYPE + && is_std_allocator (TREE_TYPE (atype))) + { + STRIP_NOPS (arg); + if (TREE_CODE (arg) == ADDR_EXPR) + { + tree *ap = &TREE_OPERAND (arg, 0); + if (TREE_CODE (*ap) == TARGET_EXPR) + temps.safe_push (ap); + } + } + } + } + + return NULL_TREE; +} + /* If INIT initializes a standard library class, and involves a temporary - std::allocator, return a pointer to the temp. + std::allocator, use ALLOC_OBJ for all such temporaries. + + Note that this can clobber the input to build_vec_init; no unsharing is + done. To make this safe we use the TARGET_EXPR in all places rather than + pulling out the TARGET_EXPR_SLOT. Used by build_vec_init when initializing an array of e.g. strings to reuse the same temporary allocator for all of the strings. We can do this because @@ -4341,22 +4387,18 @@ find_temps_r (tree *tp, int *walk_subtrees, void *data) ??? Add an attribute to allow users to assert the same property for other classes, i.e. one object of the type is interchangeable with any other? */ -static tree* -find_allocator_temp (tree init) +static void +combine_allocator_temps (tree &init, tree &alloc_obj) { - if (TREE_CODE (init) == EXPR_STMT) - init = EXPR_STMT_EXPR (init); - if (TREE_CODE (init) == CONVERT_EXPR) - init = TREE_OPERAND (init, 0); - tree type = TREE_TYPE (init); - if (!CLASS_TYPE_P (type) || !decl_in_std_namespace_p (TYPE_NAME (type))) - return NULL; auto_vec temps; - cp_walk_tree_without_duplicates (&init, find_temps_r, &temps); + cp_walk_tree_without_duplicates (&init, find_allocator_temps_r, &temps); for (tree *p : temps) - if (is_std_allocator (TREE_TYPE (*p))) - return p; - return NULL; + { + if (!alloc_obj) + alloc_obj = *p; + else + *p = alloc_obj; + } } /* `build_vec_init' returns tree structure that performs @@ -4694,13 +4736,7 @@ build_vec_init (tree base, tree maxindex, tree init, if (one_init) { /* Only create one std::allocator temporary. */ - if (tree *this_alloc = find_allocator_temp (one_init)) - { - if (alloc_obj) - *this_alloc = alloc_obj; - else - alloc_obj = TARGET_EXPR_SLOT (*this_alloc); - } + combine_allocator_temps (one_init, alloc_obj); finish_expr_stmt (one_init); } diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array18.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array18.C new file mode 100644 index 00000000000..8c0f316789d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array18.C @@ -0,0 +1,30 @@ +// PR c++/108773 +// { dg-do compile { target c++11 } } + +#include + +namespace std { +struct __new_allocator {}; +struct allocator : __new_allocator {}; +template +struct basic_string { + basic_string(const T *, allocator = allocator()); + ~basic_string(); +}; +using string = basic_string; +template +struct array { + T _M_elems; +}; +template +struct list { + list &operator=(initializer_list); +}; +} +struct RGWSyncTraceManager { + std::list> admin_commands; + void hook_to_admin_command(); +}; +void RGWSyncTraceManager::hook_to_admin_command() { + admin_commands = {{""}, {""}}; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array19.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array19.C new file mode 100644 index 00000000000..1ede5d77339 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array19.C @@ -0,0 +1,23 @@ +// PR c++/108773 +// { dg-do compile { target c++20 } } + +#include + +namespace std { +template struct array { + _Tp _M_elems[_Nm]; +}; +template struct list { void operator=(initializer_list<_Tp>); }; +struct allocator {}; +struct basic_string { + int _M_p; + constexpr basic_string() {} + basic_string(const char *, const allocator & = allocator()); + ~basic_string(); +}; +} // namespace std + +std::list> stuff; +void foo() { + stuff = {{"", ""}, {"", ""}}; +}