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.133.124]) by sourceware.org (Postfix) with ESMTPS id 97F08386EC0E for ; Thu, 2 Jun 2022 19:17:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 97F08386EC0E Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-492-LXLToC8sNgqWtrA38c0AHQ-1; Thu, 02 Jun 2022 15:17:26 -0400 X-MC-Unique: LXLToC8sNgqWtrA38c0AHQ-1 Received: by mail-qk1-f199.google.com with SMTP id j12-20020ae9c20c000000b0069e8ac6b244so4384995qkg.1 for ; Thu, 02 Jun 2022 12:17:26 -0700 (PDT) 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=fl56cYJWtUxkQTVv5Fmr7f0/N8usqBPutctrCoNKZ20=; b=GKg04KWDJgld5fWcfHxQfQbP8Qg1I65kjj8qpdCJXDUQ4ijjt7cdZk3AB0hYR5yXjK X+6iQxoacPRn7Ttage/Cuja1VBVwmMzg/uBhLniXFOWXZYthl/K/63bkdppN+qOywEML rUKttrrSITjDqHenvdvp1XsDsXF19Lpnt0kroOfIYqhY7oboghSqCrpeMU6tszzw10IR ssbrVZDijijffrKTREf33m+qCTS77QqTfPnN9AnmsLOm3JFXAyTYpJ7xkj4yH0KhYCmz fcNhyogxYLuWQ55g0IXJboNs4824l4BDBvezdr1kb3y+fGKphcHG6vRSh1OslKzPi/PY o41A== X-Gm-Message-State: AOAM532W6TfwYo+OyRBupSucHw6UxgN/Oh67GDpIzm2srg63SYam2Wkp SLQJUKtyqMLrrKUQ3bDK71J1c5KUYVRiwzaAbGANjJAqzfmak0fo7Gihbu8ItH51vGUBlHkajQf US4hsvzNg812C+Juup8j/vdvxGGoj+r4dV0NhNEQJy8XtPoAYBw8m/shukuF1/KaJdw== X-Received: by 2002:ac8:4e86:0:b0:2f3:f4dd:82b5 with SMTP id 6-20020ac84e86000000b002f3f4dd82b5mr4829654qtp.444.1654197445379; Thu, 02 Jun 2022 12:17:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz1iJ2wsfiQPhrnyryvVtN2KTBy85BaSYXPpoCY4RndZQ5Uls4TAuGu6Mz+CTD1+NTvcDNZMg== X-Received: by 2002:ac8:4e86:0:b0:2f3:f4dd:82b5 with SMTP id 6-20020ac84e86000000b002f3f4dd82b5mr4829622qtp.444.1654197444913; Thu, 02 Jun 2022 12:17:24 -0700 (PDT) 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 n206-20020a3740d7000000b006a65c58db99sm3619063qka.64.2022.06.02.12.17.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Jun 2022 12:17:24 -0700 (PDT) From: Jason Merrill To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: more constexpr empty base [PR105795] Date: Thu, 2 Jun 2022 15:17:22 -0400 Message-Id: <20220602191722.1919120-1-jason@redhat.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <490d3f21871f98e1973283f7472abfa91c261002> References: <490d3f21871f98e1973283f7472abfa91c261002> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-13.1 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_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Thu, 02 Jun 2022 19:17:29 -0000 Following on from the previous patch, for trunk let's consistently set ctx->ctor to NULL_TREE for empty subobjects. Tested x86_64-pc-linux-gnu, applying to trunk. PR c++/105795 gcc/cp/ChangeLog: * constexpr.cc (init_subob_ctx): Clear ctx->ctor for empty subob. (cxx_eval_store_expression): Likewise. (cxx_eval_bare_aggregate): Handle null ctx->ctor. --- gcc/cp/constexpr.cc | 63 +++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 021eaa34920..1346a1d4c10 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -4695,9 +4695,17 @@ init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx, else new_ctx.object = build_ctor_subob_ref (index, type, ctx->object); } - tree elt = build_constructor (type, NULL); - CONSTRUCTOR_NO_CLEARING (elt) = true; - new_ctx.ctor = elt; + + if (is_empty_class (type)) + /* Leave ctor null for an empty subobject, they aren't represented in the + result of evaluation. */ + new_ctx.ctor = NULL_TREE; + else + { + tree elt = build_constructor (type, NULL); + CONSTRUCTOR_NO_CLEARING (elt) = true; + new_ctx.ctor = elt; + } if (TREE_CODE (value) == TARGET_EXPR) /* Avoid creating another CONSTRUCTOR when we expand the TARGET_EXPR. */ @@ -4762,11 +4770,14 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, ctx = &new_ctx; }; verify_ctor_sanity (ctx, type); - vec **p = &CONSTRUCTOR_ELTS (ctx->ctor); - vec_alloc (*p, vec_safe_length (v)); - - if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (t)) - CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor) = 1; + vec **p = nullptr; + if (ctx->ctor) + { + p = &CONSTRUCTOR_ELTS (ctx->ctor); + vec_alloc (*p, vec_safe_length (v)); + if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (t)) + CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor) = 1; + } unsigned i; tree index, value; @@ -4814,17 +4825,19 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, inner->value = elt; changed = true; } + else if (no_slot) + /* This is an initializer for an empty field; now that we've + checked that it's constant, we can ignore it. */ + changed = true; else if (index && (TREE_CODE (index) == NOP_EXPR || TREE_CODE (index) == POINTER_PLUS_EXPR)) { - /* This is an initializer for an empty base; now that we've - checked that it's constant, we can ignore it. */ + /* Old representation of empty bases. FIXME remove. */ + gcc_checking_assert (false); gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index)))); changed = true; } - else if (no_slot) - changed = true; else { if (TREE_CODE (type) == UNION_TYPE @@ -4849,6 +4862,8 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, if (*non_constant_p || !changed) return t; t = ctx->ctor; + if (!t) + t = build_constructor (type, NULL); /* We're done building this CONSTRUCTOR, so now we can interpret an element without an explicit initializer as value-initialized. */ CONSTRUCTOR_NO_CLEARING (t) = false; @@ -5833,6 +5848,16 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, valp = &cep->value; } + /* For initialization of an empty base, the original target will be + *(base*)this, evaluation of which resolves to the object + argument, which has the derived type rather than the base type. */ + if (!empty_base && !(same_type_ignoring_top_level_qualifiers_p + (initialized_type (init), type))) + { + gcc_assert (is_empty_class (TREE_TYPE (target))); + empty_base = true; + } + /* Detect modifying a constant object in constexpr evaluation. We have found a const object that is being modified. Figure out if we need to issue an error. Consider @@ -5901,7 +5926,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, *valp = build_constructor (type, NULL); CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init; } - new_ctx.ctor = *valp; + new_ctx.ctor = empty_base ? NULL_TREE : *valp; new_ctx.object = target; /* Avoid temporary materialization when initializing from a TARGET_EXPR. We don't need to mess with AGGR_EXPR_SLOT/VEC_INIT_EXPR_SLOT because @@ -5931,16 +5956,10 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, gcc_checking_assert (!*valp || (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (*valp), type))); - if (empty_base || !(same_type_ignoring_top_level_qualifiers_p - (initialized_type (init), type))) + if (empty_base) { - /* For initialization of an empty base, the original target will be - *(base*)this, evaluation of which resolves to the object - argument, which has the derived type rather than the base type. In - this situation, just evaluate the initializer and return, since - there's no actual data to store, and we didn't build a CONSTRUCTOR. */ - gcc_assert (is_empty_class (TREE_TYPE (target))); - empty_base = true; + /* Just evaluate the initializer and return, since there's no actual data + to store, and we didn't build a CONSTRUCTOR. */ if (!*valp) { /* But do make sure we have something in *valp. */ base-commit: 37e4e7f77d8f7b7e911bf611a0f8edbc3a850c7a prerequisite-patch-id: ac34f6c98de0fcc6de406dceff28b84559add384 -- 2.27.0