From patchwork Fri Apr 28 19:05:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1775094 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=KnPt9tb1; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Q7MWt1zXxz23td for ; Sat, 29 Apr 2023 05:06:00 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DBE9F3858D37 for ; Fri, 28 Apr 2023 19:05:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DBE9F3858D37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682708757; bh=SG461GRlQo96r7IG+rg1AdppDZXpqRqQnib9ovtSN20=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=KnPt9tb12PqRlHNR3E5JCnGEtmNhPe3+kdNnPM1r7U1/9im37lL0oHtFVaJC3f6LI rNbetRDdfSLdgAXFITQ2fDSNCuI0vYPPeF8cu72CvmGqYfiullpprTKFOixYfJj9py FcYJ71oA38QwQB0/neqKmlAHFbOlIoagbk0bl3+o= 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 592163858413 for ; Fri, 28 Apr 2023 19:05:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 592163858413 Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-497-B3VqokZQNEGJdYhOAYK8zQ-1; Fri, 28 Apr 2023 15:05:14 -0400 X-MC-Unique: B3VqokZQNEGJdYhOAYK8zQ-1 Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-3ef6c0a9212so1362641cf.2 for ; Fri, 28 Apr 2023 12:05:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682708714; x=1685300714; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=SG461GRlQo96r7IG+rg1AdppDZXpqRqQnib9ovtSN20=; b=lc+JBZTPB/cJRYNIu3KH78VwOjr1fA8Kh+sAh8WOhTeTWcrQuetvoCE8NYPXf5N7+k NYd012rGRcYK8ItKngWzaQftroCD36HEbqC7p1gwD8x3S872qQeRGjkhZPvZ8D2la7UF ejhZYfOmR/wQvLNX8iB9ZDKclaoVRROCLAKJ9Gf1PdmwFPr5H/21P7AecoESl7Mq11DG FaksvPKGwCujV4oGRmkVmi3gFFyvMwaMxArqt3XqNmGrSuiWbrAgM40Z2IUQaS26UoU6 dsqfmtjTZAt0YguFqU5d/X+fv9FiHzjXUkfBgNBpqqX0d5azhdP4lLZ4F5g30A4Y4EKv ou+g== X-Gm-Message-State: AC+VfDy/ZGWGjkIA3yMOchMGueRoY2lti+y9f1Tqswjjovu8/nrdMi0p wdfXknIi5ybQrm9VJbnSxn3hJcwoJ4pduf3zkTfvBQzsOSmky8EoORwDliaZiE5bPAKZWW9JyrB IYjjrx4Zr9V+Y+j0weBRWn97yIAFwE4fF9Ltm7kKm9KNvDOfsXm5G7Un7BIkdX1PwtorEIaXjdB Q= X-Received: by 2002:a05:622a:2c7:b0:3ed:a811:23dd with SMTP id a7-20020a05622a02c700b003eda81123ddmr11003943qtx.41.1682708713924; Fri, 28 Apr 2023 12:05:13 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6Vn8Kx0Xc8UUFouQkthwF+aL6KHkRbO5z4B8tNBNM3lbsKjwnW6X3keJ4k4ZNBLu4OthNSgA== X-Received: by 2002:a05:622a:2c7:b0:3ed:a811:23dd with SMTP id a7-20020a05622a02c700b003eda81123ddmr11003884qtx.41.1682708713556; Fri, 28 Apr 2023 12:05:13 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id a9-20020ac844a9000000b003d3a34d2eb2sm7309043qto.41.2023.04.28.12.05.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Apr 2023 12:05:13 -0700 (PDT) To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] c++: RESULT_DECL replacement in constexpr call result [PR105440] Date: Fri, 28 Apr 2023 15:05:08 -0400 Message-ID: <20230428190508.4091082-1-ppalka@redhat.com> X-Mailer: git-send-email 2.40.1.445.gf85cd430b1 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.8 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, RCVD_IN_MSPIKE_H2, 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-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" After mechanically replacing RESULT_DECL within a constexpr call result (for sake of RVO), we can in some cases simplify the call result further. In the below testcase the result of get() during evaluation of a's initializer is the self-referential CONSTRUCTOR: {._M_p=(char *) &._M_local_buf} which after replacing RESULT_DECL with ctx->object (aka *D.2603, where the D.2603 temporary points to the current element of _M_elems under construction) becomes: {._M_p=(char *) &D.2603->_M_local_buf} but what we really want is: {._M_p=(char *) &a._M_elems[0]._M_local_buf}. so that the value of _M_p is independent of the value of the mutable D.2603 temporary. So to that end, it seems we should constexpr evaluate the result again after RESULT_DECL replacement, which is what this patch implements. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? PR libstdc++/105440 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): If any RESULT_DECLs get replaced in the call result, try further evaluating the result. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-dtor16.C: New test. --- gcc/cp/constexpr.cc | 12 +++++- gcc/testsuite/g++.dg/cpp2a/constexpr-dtor16.C | 39 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor16.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index d1097764b10..22a1609e664 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -3213,7 +3213,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, && CLASS_TYPE_P (TREE_TYPE (res)) && !is_empty_class (TREE_TYPE (res))) if (replace_decl (&result, res, ctx->object)) - cacheable = false; + { + cacheable = false; + result = cxx_eval_constant_expression (ctx, result, lval, + non_constant_p, + overflow_p); + } } else /* Couldn't get a function copy to evaluate. */ @@ -5988,9 +5993,12 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, object = probe; else { + tree orig_probe = probe; probe = cxx_eval_constant_expression (ctx, probe, vc_glvalue, non_constant_p, overflow_p); evaluated = true; + if (orig_probe == target) + target = probe; if (*non_constant_p) return t; } @@ -6154,7 +6162,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, if (!empty_base && !(same_type_ignoring_top_level_qualifiers_p (initialized_type (init), type))) { - gcc_assert (is_empty_class (TREE_TYPE (target))); + gcc_assert (is_empty_class (TREE_TYPE (TREE_OPERAND (t, 0)))); empty_base = true; } diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor16.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor16.C new file mode 100644 index 00000000000..707a3e025b1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor16.C @@ -0,0 +1,39 @@ +// PR c++/105440 +// { dg-do compile { target c++20 } } + +struct basic_string { + char _M_local_buf[32]; + char* _M_p; + constexpr basic_string() : _M_p{_M_local_buf} { } + constexpr void f() { if (_M_p) { } } + constexpr ~basic_string() { if (_M_p) { } } +}; + +template +struct array { + basic_string _M_elems[N]; +}; + +constexpr basic_string get() { return {}; } + +constexpr bool f1() { + array<1> a{get()}; + a._M_elems[0].f(); + + return true; +} + +constexpr bool f2() { + array<2> a2{get(), get()}; + array<3> a3{get(), get(), get()}; + + for (basic_string& e : a2._M_elems) + e.f(); + for (basic_string& e : a3._M_elems) + e.f(); + + return true; +} + +static_assert(f1()); +static_assert(f2());