From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 73998 invoked by alias); 7 May 2019 22:37:13 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 73915 invoked by uid 89); 7 May 2019 22:37:12 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.4 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=destroying, fn, HX-Received:108a, sk:primary X-HELO: mail-qk1-f196.google.com Received: from mail-qk1-f196.google.com (HELO mail-qk1-f196.google.com) (209.85.222.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 07 May 2019 22:37:10 +0000 Received: by mail-qk1-f196.google.com with SMTP id g190so2204764qkf.8 for ; Tue, 07 May 2019 15:37:10 -0700 (PDT) Return-Path: Received: from orpheus.redhat.com (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id f7sm1060117qth.41.2019.05.07.15.37.07 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 May 2019 15:37:07 -0700 (PDT) From: Jason Merrill To: gcc-patches@gcc.gnu.org Subject: [C++ PATCH] PR c++/90171 - reorganize usual_deallocation_fn_p Date: Tue, 07 May 2019 22:37:00 -0000 Message-Id: <20190507223706.20832-1-jason@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2019-05/txt/msg00331.txt.bz2 When fixing 90171 it struck me as undesirable to have so many separate functions that all needed to know about the definition of a usual deallocation function. So this patch condenses them into one. I left destroying_delete_p because it is used by other files as well. Tested x86_64-pc-linux-gnu, applying to trunk. * call.c (struct dealloc_info): New. (usual_deallocation_fn_p): Take a dealloc_info*. (aligned_deallocation_fn_p, sized_deallocation_fn_p): Remove. (build_op_delete_call): Adjust. --- gcc/cp/call.c | 144 ++++++++++++++++++++--------------------------- gcc/cp/ChangeLog | 8 +++ 2 files changed, 70 insertions(+), 82 deletions(-) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 1a79017eff4..20db2974b56 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6348,63 +6348,22 @@ destroying_delete_p (tree t) return std_destroying_delete_t_p (type) ? type : NULL_TREE; } -/* Returns true iff T, an element of an OVERLOAD chain, is a usual deallocation - function (3.7.4.2 [basic.stc.dynamic.deallocation]) with a parameter of - std::align_val_t. */ - -static bool -aligned_deallocation_fn_p (tree t) +struct dealloc_info { - if (!aligned_new_threshold) - return false; - - /* A template instance is never a usual deallocation function, - regardless of its signature. */ - if (TREE_CODE (t) == TEMPLATE_DECL - || primary_template_specialization_p (t)) - return false; - - tree a = FUNCTION_ARG_CHAIN (t); - if (destroying_delete_p (t)) - a = TREE_CHAIN (a); - if (same_type_p (TREE_VALUE (a), align_type_node) - && TREE_CHAIN (a) == void_list_node) - return true; - if (!same_type_p (TREE_VALUE (a), size_type_node)) - return false; - a = TREE_CHAIN (a); - if (a && same_type_p (TREE_VALUE (a), align_type_node) - && TREE_CHAIN (a) == void_list_node) - return true; - return false; -} + bool sized; + bool aligned; + tree destroying; +}; -/* Returns true if FN is a usual deallocation fn with a size_t parameter. */ +/* Returns true iff T, an element of an OVERLOAD chain, is a usual deallocation + function (3.7.4.2 [basic.stc.dynamic.deallocation]). If so, and DI is + non-null, also set *DI. */ static bool -sized_deallocation_fn_p (tree fn) +usual_deallocation_fn_p (tree t, dealloc_info *di) { - tree t = FUNCTION_ARG_CHAIN (fn); - if (destroying_delete_p (fn)) - t = TREE_CHAIN (t); - if (!t || !same_type_p (TREE_VALUE (t), size_type_node)) - return false; - t = TREE_CHAIN (t); - if (t == void_list_node) - return true; - if (aligned_new_threshold && t - && same_type_p (TREE_VALUE (t), align_type_node) - && TREE_CHAIN (t) == void_list_node) - return true; - return false; -} + if (di) *di = dealloc_info(); -/* Returns true iff T, an element of an OVERLOAD chain, is a usual - deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]). */ - -bool -usual_deallocation_fn_p (tree t) -{ /* A template instance is never a usual deallocation function, regardless of its signature. */ if (TREE_CODE (t) == TEMPLATE_DECL @@ -6418,17 +6377,33 @@ usual_deallocation_fn_p (tree t) - optionally, a parameter of type std::align_val_t. */ bool global = DECL_NAMESPACE_SCOPE_P (t); tree chain = FUNCTION_ARG_CHAIN (t); - if (!chain) - return false; - if (destroying_delete_p (t)) - chain = TREE_CHAIN (chain); - if (chain == void_list_node - || ((!global || flag_sized_deallocation) - && sized_deallocation_fn_p (t))) - return true; - if (aligned_deallocation_fn_p (t)) - return true; - return false; + if (chain && destroying_delete_p (t)) + { + if (di) di->destroying = TREE_VALUE (chain); + chain = TREE_CHAIN (chain); + } + if (chain + && (!global || flag_sized_deallocation) + && same_type_p (TREE_VALUE (chain), size_type_node)) + { + if (di) di->sized = true; + chain = TREE_CHAIN (chain); + } + if (chain && aligned_new_threshold + && same_type_p (TREE_VALUE (chain), align_type_node)) + { + if (di) di->aligned = true; + chain = TREE_CHAIN (chain); + } + return (chain == void_list_node); +} + +/* Just return whether FN is a usual deallocation function. */ + +bool +usual_deallocation_fn_p (tree fn) +{ + return usual_deallocation_fn_p (fn, NULL); } /* Build a call to operator delete. This has to be handled very specially, @@ -6457,6 +6432,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, { tree fn = NULL_TREE; tree fns, fnname, type, t; + dealloc_info di_fn = { }; if (addr == error_mark_node) return error_mark_node; @@ -6575,11 +6551,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (fns)); iter; ++iter) { tree elt = *iter; - if (usual_deallocation_fn_p (elt)) + dealloc_info di_elt; + if (usual_deallocation_fn_p (elt, &di_elt)) { if (!fn) { fn = elt; + di_fn = di_elt; continue; } @@ -6587,12 +6565,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, operator delete, all deallocation functions that are not destroying operator deletes are eliminated from further consideration. */ - bool fn_destroying = destroying_delete_p (fn); - bool elt_destroying = destroying_delete_p (elt); - if (elt_destroying != fn_destroying) + if (di_elt.destroying != di_fn.destroying) { - if (elt_destroying) - fn = elt; + if (di_elt.destroying) + { + fn = elt; + di_fn = di_elt; + } continue; } @@ -6606,13 +6585,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, if (aligned_new_threshold) { bool want_align = type_has_new_extended_alignment (type); - bool fn_align = aligned_deallocation_fn_p (fn); - bool elt_align = aligned_deallocation_fn_p (elt); - - if (elt_align != fn_align) + if (di_elt.aligned != di_fn.aligned) { - if (want_align == elt_align) - fn = elt; + if (want_align == di_elt.aligned) + { + fn = elt; + di_fn = di_elt; + } continue; } } @@ -6639,11 +6618,12 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, /* We need a cookie to determine the array size. */ want_size = false; } - bool fn_size = sized_deallocation_fn_p (fn); - bool elt_size = sized_deallocation_fn_p (elt); - gcc_assert (fn_size != elt_size); - if (want_size == elt_size) - fn = elt; + gcc_assert (di_fn.sized != di_elt.sized); + if (want_size == di_elt.sized) + { + fn = elt; + di_fn = di_elt; + } } } @@ -6678,7 +6658,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, } else { - tree destroying = destroying_delete_p (fn); + tree destroying = di_fn.destroying; if (destroying) { /* Strip const and volatile from addr but retain the type of the @@ -6696,9 +6676,9 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, args->quick_push (addr); if (destroying) args->quick_push (destroying); - if (sized_deallocation_fn_p (fn)) + if (di_fn.sized) args->quick_push (size); - if (aligned_deallocation_fn_p (fn)) + if (di_fn.aligned) { tree al = build_int_cst (align_type_node, TYPE_ALIGN_UNIT (type)); args->quick_push (al); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d90cc099767..dade3e0c8b9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2019-05-06 Jason Merrill + + PR c++/90171 - reorganize usual_deallocation_fn_p + * call.c (struct dealloc_info): New. + (usual_deallocation_fn_p): Take a dealloc_info*. + (aligned_deallocation_fn_p, sized_deallocation_fn_p): Remove. + (build_op_delete_call): Adjust. + 2019-05-07 Jason Merrill PR c++/86485 - -Wmaybe-unused with empty class ?: base-commit: 57481cdfdc4aa2a0c61e732f9fff312a9ddfb7b6 prerequisite-patch-id: f9e234ae0c68beb8fed9e212e3da578a940c2995 prerequisite-patch-id: 855e2f35bd03f2879aa0288e383ea742b120135a -- 2.20.1