From patchwork Wed Feb 9 01:09:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 50935 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 4DF553858012 for ; Wed, 9 Feb 2022 01:10:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4DF553858012 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1644369044; bh=uCsmqIqc2n9x0p8M3jDlMxGani6kmrEno221l4dpfPU=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=KwsOiqZVQEftugJ0bqKGVu4uygdhbRz4kQJNLb1n0s8GKnlO/aBVQKVD+r/7Pr9Sy P8B0lJRmJqTqOUQj9cfX7x4xUVikW8FWOe+gyntVoDRonvuZ5Dxit0226+tMUhAeI3 +XnW+tzppVXU3KLeLy7RQsNCGXGSNgGU+hBjrCeA= 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 023F63858426 for ; Wed, 9 Feb 2022 01:09:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 023F63858426 Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-226-veFnTrT4PCO3XguDrGrujg-1; Tue, 08 Feb 2022 20:09:48 -0500 X-MC-Unique: veFnTrT4PCO3XguDrGrujg-1 Received: by mail-qv1-f72.google.com with SMTP id du13-20020a05621409ad00b0042c2949e2c1so529843qvb.19 for ; Tue, 08 Feb 2022 17:09:48 -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=uCsmqIqc2n9x0p8M3jDlMxGani6kmrEno221l4dpfPU=; b=MF+v0rNR/18ShO8SEouy0/iGSUAIHwtZ+izFk54C/D6M8amuPA8j7aEI4teo7qQB+J VE+9pRqjwp4PaMyFxpXQc/b6NRXGgJxuqFbXt7xwV+gODbbkF4pfq/gE8pC/B0O1s9WF zZt0zNl4NrtPMUOClUhHkuBPzxsy/jAoEAwSV2F/OsVQ6Kd67OzNbPftK1fcM7Ke3wGN j1rC/p8bZCs209l82CUlFA3GgrtBA0K42FDBa2+zrm+9HK2IfJadKYoeZV64LAnJQUTD E0s+jREF/i6DGB7g6bfNJrjxNTiAguGjcraBVISHfZqsEgWukCOYU2XSyu7ploDZf+Be /lEA== X-Gm-Message-State: AOAM531sXi0CCa1uTmK8o9zPWur7ftRJ4QbGeOVQ9MeEJjAOXuDOaxi0 dBTaiBL/rHpCFftAtS0hQBdx2BsDBXRlTSXkODYAFt8Qd1xZAM3DWGjrGm3kJpikVSKMCF1fuQJ RtgtNphEP3yRwDkTJU12G+dduw74BBDJVRGraJqTDRhB7N1n1mjbc1ObohAUCeHYR6A== X-Received: by 2002:a37:ef0a:: with SMTP id j10mr4333251qkk.68.1644368987844; Tue, 08 Feb 2022 17:09:47 -0800 (PST) X-Google-Smtp-Source: ABdhPJxUejAoTzTiM3A2/VdkNC0hibXEDE9pWSH5iOndFaJsuXC5wrmYdlGULRulF5WtZ6ZzUpLBJg== X-Received: by 2002:a37:ef0a:: with SMTP id j10mr4333232qkk.68.1644368987333; Tue, 08 Feb 2022 17:09:47 -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 m22sm7974902qkn.35.2022.02.08.17.09.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Feb 2022 17:09:46 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: cleanup constant-init'd members [PR96876] Date: Tue, 8 Feb 2022 20:09:44 -0500 Message-Id: <20220209010944.1100060-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.0 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" This is a case missed by my recent fixes to aggregate initialization and exception cleanup for PR94041 et al: we also need to clean up members with constant initialization if initialization of a later member throws. It also occurs to me that we needn't bother building the cleanups if -fno-exceptions; build_vec_init already doesn't. Tested x86_64-pc-linux-gnu, applying to trunk. PR c++/96876 gcc/cp/ChangeLog: * typeck2.cc (split_nonconstant_init_1): Push cleanups for preceding members with constant initialization. (maybe_push_temp_cleanup): Do nothing if -fno-exceptions. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/aggr-base11.C: New test. * g++.dg/eh/aggregate2.C: New test. --- gcc/cp/typeck2.cc | 26 +++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/aggr-base11.C | 19 +++++++++++++++++ gcc/testsuite/g++.dg/eh/aggregate2.C | 27 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1z/aggr-base11.C create mode 100644 gcc/testsuite/g++.dg/eh/aggregate2.C base-commit: 73f4a989b7f8aeaf8bff37e7f33b65d26b8f179f diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc index 4015bd53257..39d03e4c3c4 100644 --- a/gcc/cp/typeck2.cc +++ b/gcc/cp/typeck2.cc @@ -467,6 +467,8 @@ cxx_incomplete_type_error (location_t loc, const_tree value, const_tree type) static void maybe_push_temp_cleanup (tree sub, vec **flags) { + if (!flag_exceptions) + return; if (tree cleanup = cxx_maybe_build_cleanup (sub, tf_warning_or_error)) { @@ -496,6 +498,7 @@ split_nonconstant_init_1 (tree dest, tree init, bool last, bool array_type_p = false; bool complete_p = true; HOST_WIDE_INT num_split_elts = 0; + tree last_split_elt = NULL_TREE; switch (TREE_CODE (type)) { @@ -572,6 +575,7 @@ split_nonconstant_init_1 (tree dest, tree init, bool last, else { /* Mark element for removal. */ + last_split_elt = field_index; CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE; if (idx < tidx) tidx = idx; @@ -584,6 +588,7 @@ split_nonconstant_init_1 (tree dest, tree init, bool last, flags)); /* Mark element for removal. */ + last_split_elt = field_index; CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE; if (idx < tidx) tidx = idx; @@ -593,6 +598,26 @@ split_nonconstant_init_1 (tree dest, tree init, bool last, { tree code; + /* Push cleanups for any preceding members with constant + initialization. */ + if (CLASS_TYPE_P (type)) + for (tree prev = (last_split_elt ? + DECL_CHAIN (last_split_elt) + : TYPE_FIELDS (type)); + ; prev = DECL_CHAIN (prev)) + { + prev = next_initializable_field (prev); + if (prev == field_index) + break; + tree ptype = TREE_TYPE (prev); + if (type_build_dtor_call (ptype)) + { + tree pcref = build3 (COMPONENT_REF, ptype, dest, prev, + NULL_TREE); + maybe_push_temp_cleanup (pcref, flags); + } + } + /* Mark element for removal. */ CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE; if (idx < tidx) @@ -645,6 +670,7 @@ split_nonconstant_init_1 (tree dest, tree init, bool last, maybe_push_temp_cleanup (sub, flags); } + last_split_elt = field_index; num_split_elts++; } } diff --git a/gcc/testsuite/g++.dg/cpp1z/aggr-base11.C b/gcc/testsuite/g++.dg/cpp1z/aggr-base11.C new file mode 100644 index 00000000000..88625dc9533 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/aggr-base11.C @@ -0,0 +1,19 @@ +// PR c++/96876 +// { dg-do compile { target c++17 } } + +struct B { +protected: + ~B() {} // { dg-message "" } +}; + +struct A { }; +struct C1: B { int n; }; +struct C2: A, B { int n; }; + +A af (); +int f(); + +void g() { + C1 c1{ {}, f()}; // { dg-error "protected" } + C2 c2{ af(), {}, f()}; // { dg-error "protected" } +} diff --git a/gcc/testsuite/g++.dg/eh/aggregate2.C b/gcc/testsuite/g++.dg/eh/aggregate2.C new file mode 100644 index 00000000000..8424d63de2d --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/aggregate2.C @@ -0,0 +1,27 @@ +// PR c++/96876 +// { dg-do run { target c++11 } } + +int d; +struct B { + ~B() { ++d; } +}; + +struct C1 { B b; int n; }; +struct C2 { int i; B b; int n; }; + +int f() { throw 24; return 42; } +int dummy; +int g() { ++dummy; return 42; } + +int main() { + try { + C1 c{{}, f()}; + } catch (...) { } + + try { + C2 c{g(), {}, f()}; + } catch (...) { } + + if (d != 2) + __builtin_abort (); +}