From patchwork Sat Jan 8 02:02:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 49749 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 AC93A3857C7F for ; Sat, 8 Jan 2022 02:03:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AC93A3857C7F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1641607386; bh=YHxSmQsnz2f0JcMKldclwAMGfLOeWC79+FwR353e/LU=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=yJseGNcfv+Sbd+wo9GwF0Y8dX+gmGvoteHKaOUqZRTu9WSr7Nj2uDkKgRyAINWjh0 kaLxgwlbUNAfJN9VnVkWbIYwsiPz8pDiPpQlAUwTa1bcKzm75IaRR49CUECJCukwME o43ZwlddBFG44PPt8avkix5PXbXRkn/ShRBxMtlk= 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.129.124]) by sourceware.org (Postfix) with ESMTPS id 617293858421 for ; Sat, 8 Jan 2022 02:02:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 617293858421 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-353-cxr1nVjsMrmkpbk5X4uAZw-1; Fri, 07 Jan 2022 21:02:30 -0500 X-MC-Unique: cxr1nVjsMrmkpbk5X4uAZw-1 Received: by mail-qt1-f197.google.com with SMTP id z17-20020ac84311000000b002c5c70c851cso6272692qtm.23 for ; Fri, 07 Jan 2022 18:02:29 -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=YHxSmQsnz2f0JcMKldclwAMGfLOeWC79+FwR353e/LU=; b=lOtlDfAzc2inpRwGsQmfKig12AAjHJ6DWit+Ecc3Mnux2xSsgyWmuFwkwmpOsvAWSH F4bY37QhnH94fPwqehrSneeLS1lyigGftncTiCvqVgvFVZhFFJ9XGOOmcFLGBAXqqW5g fn44jh6AOQ/p+ZMvL/e2uIep5ij55vQMQUlMjWlmskPiRRf2nMqpNB9LxU4B+lJx8q5F wLEprrZcNihjWpexyO7M8Zfurr1mO9ivAn5mRo3WhVzgTYZCTYwFdmf/yThcARRM/yUg Cllm1xWS6dsUB6HECuZPbPogn0I6YCQ0rdp5CMIqfCk1tDuJoKO3KulbPdPllYI7Et/M USGg== X-Gm-Message-State: AOAM532EMutMaloBLpo7EWfkGViv8DNlG0VStl2Y9KefHE1zgQsc0oiY +WR6lKwsZnk7w0nMIguUtznGVcNW4E03s/9yfWD1Z8kpPK2bxfCl22N0w0q77PHxSSjvWd0YUvA 90ulzvCZQt/Ax4ZNBJDhfb6T97XQWtE+NRlKsBwLkRHK+YHcP0ml6a5hAb9urk5xNMQ== X-Received: by 2002:a05:620a:b1b:: with SMTP id t27mr8577866qkg.609.1641607349114; Fri, 07 Jan 2022 18:02:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJxCvsueKn2ggLL/aXMbCHo5rvh5h/cCEBbIHS4vSoKI4eqsDyD14vz9Uxp+FMb3u3urr4/pDg== X-Received: by 2002:a05:620a:b1b:: with SMTP id t27mr8577844qkg.609.1641607348533; Fri, 07 Jan 2022 18:02:28 -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 y124sm239762qkd.105.2022.01.07.18.02.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 18:02:27 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: destroying delete, throw in new-expr [PR100588] Date: Fri, 7 Jan 2022 21:02:25 -0500 Message-Id: <20220108020225.3093741-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.2 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, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP 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 standard says that a destroying operator delete is preferred, but that only applies to the delete-expression, not the cleanup if a new-expression initialization throws. As a result of this patch, several of the destroying delete tests don't get EH cleanups, but I'm turning off the warning in cases where the initialization can't throw anyway. It's unclear what should happen if the class does not declare a non-deleting operator delete; a proposal in CWG was to call the global delete, which makes sense to me if the class doesn't declare its own operator new. If it does, we warn and don't call any deallocation function if initialization throws. Tested x86_64-pc-linux-gnu, applying to trunk. PR c++/100588 gcc/cp/ChangeLog: * call.c (build_op_delete_call): Ignore destroying delete if alloc_fn. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/destroying-delete6.C: New test. --- gcc/cp/call.c | 31 ++++++++++++++-- .../g++.dg/cpp2a/destroying-delete5.C | 4 +-- .../g++.dg/cpp2a/destroying-delete6.C | 36 +++++++++++++++++++ 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C base-commit: 6cd51207f5732b5258e883e9030b94c987b6d696 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7f7ee88deed..44fc6d0f695 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7267,6 +7267,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, tree oaddr = addr; addr = cp_convert (ptr_type_node, addr, complain); + tree excluded_destroying = NULL_TREE; + if (placement) { /* "A declaration of a placement deallocation function matches the @@ -7352,6 +7354,15 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, dealloc_info di_elt; if (usual_deallocation_fn_p (elt, &di_elt)) { + /* If we're called for an EH cleanup in a new-expression, we can't + use a destroying delete; the exception was thrown before the + object was constructed. */ + if (alloc_fn && di_elt.destroying) + { + excluded_destroying = elt; + continue; + } + if (!fn) { fn = elt; @@ -7499,6 +7510,14 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, return ret; } + /* If there's only a destroying delete that we can't use because the + object isn't constructed yet, and we used global new, use global + delete as well. */ + if (excluded_destroying + && DECL_NAMESPACE_SCOPE_P (alloc_fn)) + return build_op_delete_call (code, addr, size, true, placement, + alloc_fn, complain); + /* [expr.new] If no unambiguous matching deallocation function can be found, @@ -7508,8 +7527,16 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, { if ((complain & tf_warning) && !placement) - warning (0, "no corresponding deallocation function for %qD", - alloc_fn); + { + bool w = warning (0, + "no corresponding deallocation function for %qD", + alloc_fn); + if (w && excluded_destroying) + inform (DECL_SOURCE_LOCATION (excluded_destroying), "destroying " + "delete %qD cannot be used to release the allocated memory" + " if the initialization throws because the object is not " + "constructed yet", excluded_destroying); + } return NULL_TREE; } diff --git a/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C b/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C index 553c964b9e9..6113d7f3d9e 100644 --- a/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C +++ b/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C @@ -18,7 +18,7 @@ void * Expression::operator new(std::size_t sz) int i; -void Expression::operator delete(Expression *p, std::destroying_delete_t) +void Expression::operator delete(Expression *p, std::destroying_delete_t) // { dg-message "destroying delete" } { Expression * e = p; ::i = e->i; @@ -28,7 +28,7 @@ void Expression::operator delete(Expression *p, std::destroying_delete_t) int main() { - auto p = new Expression(); + auto p = new Expression(); // { dg-warning "no corresponding dealloc" } p->i = 1; delete p; if (i != 1) diff --git a/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C b/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C new file mode 100644 index 00000000000..be783738082 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C @@ -0,0 +1,36 @@ +// PR c++/100588 +// { dg-do run { target c++20 } } + +extern "C" void abort (); +extern "C" int puts (const char *); +#include + +#ifndef DEBUG +#define puts(S) +#endif + +class A { + public: + A() { throw 42; } + ~A() { puts("A::~A"); } + + void operator delete(void* p) { + puts("regular delete invoked"); + ::operator delete(p); + } + + void operator delete(A* p, std::destroying_delete_t) { + puts("destroying delete invoked"); + p->~A(); + ::operator delete(p); + abort (); + } +}; + +int main() { + try { + new A; + } catch (int) { + } +} +