From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1851) id 0420C385BF81; Thu, 9 Apr 2020 13:53:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0420C385BF81 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1586440436; bh=YZUdOBawb7E6i+Sgw2/6CA1mVCy1o9lhE3rOlsjJWAA=; h=From:To:Subject:Date:From; b=V+0MGNY8vXx/q901UMTsGa2rXlY2/WS+SNBfQuj0t9zj8cTDZPAvaclp4oKXlb/4i v8OldXAwyEEKdHWCamwc3LLElb3K1HfW2aZYU7YeByAMb42znCcwE89c2iNq1NiF7B o4rIYSNAlM3uxFI9bBl/FGPdU2U5JU04XgLBgdn4= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Martin Liska To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/marxin/heads/PR94314-fix-new-delete-pair-deletion-part-3)] List valid pairs for new and delete operators. X-Act-Checkin: gcc X-Git-Author: Martin Liska X-Git-Refname: refs/users/marxin/heads/PR94314-fix-new-delete-pair-deletion-part-3 X-Git-Oldrev: 148289004696940ea5828d19e63a1e3791a2fb70 X-Git-Newrev: dc1f52d856c7d4fcda4a632963158dce2af24b43 Message-Id: <20200409135356.0420C385BF81@sourceware.org> Date: Thu, 9 Apr 2020 13:53:56 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Apr 2020 13:53:56 -0000 https://gcc.gnu.org/g:dc1f52d856c7d4fcda4a632963158dce2af24b43 commit dc1f52d856c7d4fcda4a632963158dce2af24b43 Author: Martin Liska Date: Thu Apr 9 15:50:58 2020 +0200 List valid pairs for new and delete operators. gcc/ChangeLog: 2020-04-09 Martin Liska PR c++/94314 * cgraphclones.c (set_new_clone_decl_and_node_flags): Drop DECL_IS_REPLACEABLE_OPERATOR during cloning. * tree-ssa-dce.c (valid_new_delete_pair_p): New function. (propagate_necessity): Check operator names. gcc/testsuite/ChangeLog: 2020-04-09 Martin Liska PR c++/94314 * g++.dg/pr94314-4.C: New test. Diff: --- gcc/cgraphclones.c | 2 + gcc/testsuite/g++.dg/pr94314-4.C | 33 ++++++++++++++++ gcc/tree-ssa-dce.c | 83 +++++++++++++++++++++++++++++++++++----- 3 files changed, 108 insertions(+), 10 deletions(-) diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index c73b8f810f0..8f541a28b6e 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -165,6 +165,7 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node) DECL_STATIC_DESTRUCTOR (new_node->decl) = 0; DECL_SET_IS_OPERATOR_NEW (new_node->decl, 0); DECL_SET_IS_OPERATOR_DELETE (new_node->decl, 0); + DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0; new_node->externally_visible = 0; new_node->local = 1; @@ -1030,6 +1031,7 @@ cgraph_node::create_version_clone_with_body DECL_STATIC_DESTRUCTOR (new_decl) = 0; DECL_SET_IS_OPERATOR_NEW (new_decl, 0); DECL_SET_IS_OPERATOR_DELETE (new_decl, 0); + DECL_IS_REPLACEABLE_OPERATOR (new_decl) = 0; /* Create the new version's call-graph node. and update the edges of the new node. */ diff --git a/gcc/testsuite/g++.dg/pr94314-4.C b/gcc/testsuite/g++.dg/pr94314-4.C new file mode 100644 index 00000000000..afa2a443dc4 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr94314-4.C @@ -0,0 +1,33 @@ +/* PR c++/94314. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-tree-cddce-details -std=c++14" } */ +/* { dg-additional-options "-fdelete-null-pointer-checks" } */ + +#include + +int count = 0; + +__attribute__((malloc, noinline)) void* operator new[](__SIZE_TYPE__ sz) { + ++count; + return ::operator new(sz); +} + +void operator delete[](void* ptr) noexcept { + --count; + ::operator delete(ptr); +} + +void operator delete[](void* ptr, __SIZE_TYPE__ sz) noexcept { + --count; + ::operator delete(ptr, sz); +} + +int main() { + delete[] new int[1]; + if (count != 0) + __builtin_abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-not "Deleting : operator delete" "cddce1"} } */ diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index fd5f24c746c..ef8c32b9f99 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -646,6 +646,62 @@ degenerate_phi_p (gimple *phi) return true; } +/* Return that NEW_CALL and DELETE_CALL are a valid pair of new + and delete operators. */ + +static bool +valid_new_delete_pair_p (gimple *new_call, gimple *delete_call) +{ + const char *new_name + = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (gimple_call_fndecl (new_call))); + const char *delete_name + = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (gimple_call_fndecl (delete_call))); + + /* Invalid pairs: + non-[] and [] + aligned and non-aligned + */ + + const char *valid_pairs[][2] = { + /* non-[] operators. */ + {"_Znwm", "_ZdlPv" }, + {"_Znwm", "_ZdlPvm" }, + {"_Znwm", "_ZdlPvRKSt9nothrow_t" }, + {"_ZnwmRKSt9nothrow_t", "_ZdlPv" }, + {"_ZnwmRKSt9nothrow_t", "_ZdlPvm" }, + {"_ZnwmRKSt9nothrow_t", "_ZdlPvRKSt9nothrow_t" }, + /* non-[] operators with alignment. */ + {"_ZnwmSt11align_val_t", "_ZdlPvmSt11align_val_t" }, + {"_ZnwmSt11align_val_t", "_ZdlPvSt11align_val_t" }, + {"_ZnwmSt11align_val_t", "_ZdlPvSt11align_val_tRKSt9nothrow_t" }, + {"_ZnwmSt11align_val_tRKSt9nothrow_t", "_ZdlPvmSt11align_val_t" }, + {"_ZnwmSt11align_val_tRKSt9nothrow_t", "_ZdlPvSt11align_val_t" }, + {"_ZnwmSt11align_val_tRKSt9nothrow_t", "_ZdlPvSt11align_val_tRKSt9nothrow_t" }, + /* [] operators. */ + { "_Znam", "_ZdaPv" }, + { "_Znam", "_ZdaPvm" }, + { "_Znam", "_ZdaPvRKSt9nothrow_t" }, + { "_ZnamRKSt9nothrow_t", "_ZdaPv" }, + { "_ZnamRKSt9nothrow_t", "_ZdaPvm" }, + { "_ZnamRKSt9nothrow_t", "_ZdaPvRKSt9nothrow_t" }, + /* [] operators with alignment. */ + { "_ZnamSt11align_val_t", "_ZdaPvmSt11align_val_t" }, + { "_ZnamSt11align_val_t", "_ZdaPvSt11align_val_t" }, + { "_ZnamSt11align_val_t", "_ZdaPvSt11align_val_tRKSt9nothrow_t" }, + { "_ZnamSt11align_val_tRKSt9nothrow_t", "_ZdaPvmSt11align_val_t"}, + { "_ZnamSt11align_val_tRKSt9nothrow_t", "_ZdaPvSt11align_val_t"}, + { "_ZnamSt11align_val_tRKSt9nothrow_t", "_ZdaPvSt11align_val_tRKSt9nothrow_t"}, + { NULL, NULL } + }; + + for (unsigned i = 0; valid_pairs[i][0] != NULL; i++) + if (strcmp (new_name, valid_pairs[i][0]) == 0 + && strcmp (delete_name, valid_pairs[i][1]) == 0) + return true; + + return false; +} + /* Propagate necessity using the operands of necessary statements. Process the uses on each statement in the worklist, and add all feeding statements which contribute to the calculation of this @@ -824,16 +880,23 @@ propagate_necessity (bool aggressive) || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC)) || DECL_IS_REPLACEABLE_OPERATOR_NEW_P (def_callee))) { - /* Delete operators can have alignment and (or) size as next - arguments. When being a SSA_NAME, they must be marked - as necessary. */ - if (is_delete_operator && gimple_call_num_args (stmt) >= 2) - for (unsigned i = 1; i < gimple_call_num_args (stmt); i++) - { - tree arg = gimple_call_arg (stmt, i); - if (TREE_CODE (arg) == SSA_NAME) - mark_operand_necessary (arg); - } + if (is_delete_operator) + { + if (!valid_new_delete_pair_p (def_stmt, stmt)) + mark_operand_necessary (gimple_call_arg (stmt, 0)); + + /* Delete operators can have alignment and (or) size + as next arguments. When being a SSA_NAME, they + must be marked as necessary. */ + if (gimple_call_num_args (stmt) >= 2) + for (unsigned i = 1; i < gimple_call_num_args (stmt); + i++) + { + tree arg = gimple_call_arg (stmt, i); + if (TREE_CODE (arg) == SSA_NAME) + mark_operand_necessary (arg); + } + } continue; }