From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 AA23A385802F for ; Mon, 10 Jan 2022 19:09:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AA23A385802F Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-127-_r14vWGbO46NnXdO-SwOBg-1; Mon, 10 Jan 2022 14:09:30 -0500 X-MC-Unique: _r14vWGbO46NnXdO-SwOBg-1 Received: by mail-qv1-f69.google.com with SMTP id g2-20020a0562141cc200b004123b0abe18so14110168qvd.2 for ; Mon, 10 Jan 2022 11:09: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:message-id:date:mime-version:user-agent:subject :content-language:to:references:from:in-reply-to :content-transfer-encoding; bh=fcJDP4O6F2Tq3WnM/IGIuNrCp3Wv/NqnOmQ3/nT+KTk=; b=7heYOWHdbIRZNJlVrpZcgEqnYCoD0Bi57OWdMfAKK708h2Ob1kqpqmtcBUZ+3zJJJx mbdI8pSI2w1vwdWZO+IKkLhLONfzX0sRimy2rwN8XlRGrVZPHRXd0GsruDXyk15d1OcE ukuLx94NVODs0G6ljswsYB45gzmKllLlQF9xx7myUgmPKKpyZtGtC5xwZ+HnKQ/olH0m B98q50uIRed3s5LoV8FJpdEO72Zvu3Lrxr6Dtn2wmT9OQfOKbt6UfD7PyCR60UONuzxs vWuN4OevFd8dZWQ6/t513iVhkmMJ6N1doIFSL3/2Pjvbe8znbgd3dZdDuI2F9LehWg0b QoPA== X-Gm-Message-State: AOAM533MLa3tp+ACGAhtVwAySysIjDpBJZar2AGWV/YbT142ftQQMrmT j2SRNZXfsHRkUncPyXuwJzRzl/SBCVcnKR6lwbEKTFkAfe6fK/N/QcBQRAfZrVqXN4GNxS5aOQC AH19e0Aytl9VmOVnemA== X-Received: by 2002:a37:9ecb:: with SMTP id h194mr861529qke.185.1641841768794; Mon, 10 Jan 2022 11:09:28 -0800 (PST) X-Google-Smtp-Source: ABdhPJyEj7OwzuR17GYMP3ss49vZChxIvwwUJIG8u97p7KXpnVt9pSxYjZ11fNMtTkYe9jk6c7g5+w== X-Received: by 2002:a37:9ecb:: with SMTP id h194mr861514qke.185.1641841768478; Mon, 10 Jan 2022 11:09:28 -0800 (PST) Received: from [192.168.1.149] (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 w14sm278525qta.6.2022.01.10.11.09.27 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 10 Jan 2022 11:09:27 -0800 (PST) Message-ID: <4bc548be-95bf-66cd-9bf6-faea21d13af2@redhat.com> Date: Mon, 10 Jan 2022 14:09:26 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.4.1 Subject: Re: [PATCH] c++: constexpr base-to-derived conversion with offset 0 [PR103879] To: Patrick Palka , gcc-patches@gcc.gnu.org References: <20220104165408.4063383-1-ppalka@redhat.com> From: Jason Merrill In-Reply-To: <20220104165408.4063383-1-ppalka@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit 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, NICE_REPLY_A, 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-List-Received-Date: Mon, 10 Jan 2022 19:09:33 -0000 On 1/4/22 11:54, Patrick Palka wrote: > r12-136 made us canonicalize an object/offset pair with negative offset > into one with a nonnegative offset, by iteratively absorbing the > innermost component into the offset and stopping as soon as the offset > becomes nonnegative. > > This patch strengthens this transformation to make it keep absorbing > even if the offset is already 0 as long as the innermost component is at > position 0 (and thus absorbing doesn't change the offset). This lets us > accept the two constexpr testcases below, which we'd previously reject > essentially because cxx_fold_indirect_ref wasn't able to resolve > *(B*)&b.D123 (where D123 is the base subobject A at position 0) to just b. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk? > > PR c++/103879 > > gcc/cp/ChangeLog: > > * constexpr.c (cxx_fold_indirect_ref): Split out object/offset > canonicalization step into a local lambda. Strengthen it to > absorb more components at position 0. Use it before both calls > to cxx_fold_indirect_ref_1. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp1y/constexpr-base2.C: New test. > * g++.dg/cpp1y/constexpr-base2a.C: New test. > --- > gcc/cp/constexpr.c | 38 +++++++++++++------ > gcc/testsuite/g++.dg/cpp1y/constexpr-base2.C | 21 ++++++++++ > gcc/testsuite/g++.dg/cpp1y/constexpr-base2a.C | 25 ++++++++++++ > 3 files changed, 72 insertions(+), 12 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-base2.C > create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-base2a.C > > diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c > index 72be45c9e87..1ec33a00ee5 100644 > --- a/gcc/cp/constexpr.c > +++ b/gcc/cp/constexpr.c > @@ -5144,6 +5144,25 @@ cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, > if (!INDIRECT_TYPE_P (subtype)) > return NULL_TREE; > > + /* Canonicalizes the given OBJ/OFF pair by iteratively absorbing > + the innermost component into the offset until the offset is > + nonnegative, Maybe "until it would make the offset positive" now that you continue with repeated zeros. OK with that change. > so that cxx_fold_indirect_ref_1 can identify > + more folding opportunities. */ > + auto canonicalize_obj_off = [] (tree& obj, tree& off) { > + while (TREE_CODE (obj) == COMPONENT_REF > + && (tree_int_cst_sign_bit (off) || integer_zerop (off))) > + { > + tree field = TREE_OPERAND (obj, 1); > + tree pos = byte_position (field); > + if (integer_zerop (off) && integer_nonzerop (pos)) > + /* If the offset is already 0, keep going as long as the > + component is at position 0. */ > + break; > + off = int_const_binop (PLUS_EXPR, off, pos); > + obj = TREE_OPERAND (obj, 0); > + } > + }; > > if (TREE_CODE (sub) == ADDR_EXPR) > { > tree op = TREE_OPERAND (sub, 0); > @@ -5162,7 +5181,12 @@ cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, > return op; > } > else > - return cxx_fold_indirect_ref_1 (ctx, loc, type, op, 0, empty_base); > + { > + tree off = integer_zero_node; > + canonicalize_obj_off (op, off); > + gcc_assert (integer_zerop (off)); > + return cxx_fold_indirect_ref_1 (ctx, loc, type, op, 0, empty_base); > + } > } > else if (TREE_CODE (sub) == POINTER_PLUS_EXPR > && tree_fits_uhwi_p (TREE_OPERAND (sub, 1))) > @@ -5174,17 +5198,7 @@ cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type, > if (TREE_CODE (op00) == ADDR_EXPR) > { > tree obj = TREE_OPERAND (op00, 0); > - while (TREE_CODE (obj) == COMPONENT_REF > - && tree_int_cst_sign_bit (off)) > - { > - /* Canonicalize this object/offset pair by iteratively absorbing > - the innermost component into the offset until the offset is > - nonnegative, so that cxx_fold_indirect_ref_1 can identify > - more folding opportunities. */ > - tree field = TREE_OPERAND (obj, 1); > - off = int_const_binop (PLUS_EXPR, off, byte_position (field)); > - obj = TREE_OPERAND (obj, 0); > - } > + canonicalize_obj_off (obj, off); > return cxx_fold_indirect_ref_1 (ctx, loc, type, obj, > tree_to_uhwi (off), empty_base); > } > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-base2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-base2.C > new file mode 100644 > index 00000000000..7cbf5bf32b7 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-base2.C > @@ -0,0 +1,21 @@ > +// PR c++/103879 > +// { dg-do compile { target c++14 } } > + > +struct A { > + int n = 42; > +}; > + > +struct B : A { }; > + > +struct C { > + B b; > +}; > + > +constexpr int f() { > + C c; > + A& a = static_cast(c.b); > + B& b = static_cast(a); > + return b.n; > +} > + > +static_assert(f() == 42, ""); > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-base2a.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-base2a.C > new file mode 100644 > index 00000000000..872e9bb6d6a > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-base2a.C > @@ -0,0 +1,25 @@ > +// PR c++/103879 > +// { dg-do compile { target c++14 } } > + > +struct A { > + int n = 42; > +}; > + > +struct Y { int m = 0; }; > + > +struct X : Y, A { }; > + > +struct B : X { }; > + > +struct C { > + B b; > +}; > + > +constexpr int f() { > + C c; > + A& a = static_cast(c.b); > + B& b = static_cast(a); > + return b.n; > +} > + > +static_assert(f() == 42, "");