From patchwork Thu Sep 15 18:03:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 57671 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 6E219383FBBB for ; Thu, 15 Sep 2022 18:04:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6E219383FBBB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663265046; bh=MjzA4rhsAOlMLRLXWiexiB8VEC3NpP4kcpUySOv7Kgc=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=eegORKAJ0IwuqNQH5mc2/v+BALXPkHkFEkOO2XyDeslFA7ose8ogU8E4XtFaLtTMA Fb9H7a6YOTruE5MYk+oIasYYqe+hrbtUjPMmKyo/qDBUaxF8QVEiku4ll/DrCBfyUT SqKLEpHMAv8O//K+nqXd1a8ePVwTBjHI3Cr9Oyqs= 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 1E3023857BA2 for ; Thu, 15 Sep 2022 18:03:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1E3023857BA2 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.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-189-ZLKWVLYVNvG5OgS3Jta3Hw-1; Thu, 15 Sep 2022 14:03:15 -0400 X-MC-Unique: ZLKWVLYVNvG5OgS3Jta3Hw-1 Received: by mail-qt1-f197.google.com with SMTP id h7-20020ac85047000000b0035a6794699bso15464812qtm.3 for ; Thu, 15 Sep 2022 11:03:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date; bh=MjzA4rhsAOlMLRLXWiexiB8VEC3NpP4kcpUySOv7Kgc=; b=muSTZvccFXsxjEjHwstfkuf0N5JafG21JENYsxKKCZcyeI3lvPx3wTo5rj/6BThvp7 sXyf7ZiSxC0x1tlEx53iSHuL8Bjrs/TM+wzruXybLPTo9Y2kJUVXDTHct2JBChy8vq2o avFR1Xn8dtR1Ko9sgyYW6mdJ1Jxj0cSE4LuRvYBP+/2rYFOJ1qzm4Z+Hx7dX6pDpPGHJ MLW0eUELrQHHDV7/kSZzTlwiFzZyw88URV1k6/qW5g1DwjglkOVE8gCC0FRcig6JouNg kA9LxSJlfoRQ/4Ql13Hu0etacW5m8I3SCpKQDu5fb55zEnNvAeTgKtBGaAgkyr3PySi+ DgLQ== X-Gm-Message-State: ACrzQf1hlJSDves+sQHcTxBcrdaF9aWtE4NVyY4JVTDF6lL2rsNWe8IH a+rP6sPdHAwaWEi7RbrKOhfkwKjbeYNXfI45+ECtQdNCajPsVAjhqcG9a4YmZwXwoHELN4qFUe9 S3C1AtqctI4qtMmJN5ee/y3lTXN9c1+O3cNaEJIOZFfYtgac43kkiAlAYJMQnP/grbJo= X-Received: by 2002:ac8:5a11:0:b0:35b:a2ec:2b73 with SMTP id n17-20020ac85a11000000b0035ba2ec2b73mr1064032qta.364.1663264994343; Thu, 15 Sep 2022 11:03:14 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4yyTM04p4+2J1w2y9IZRryNwVcUi3n0PxQB9o3KnlAZdSxx2j/XZ9uuiK2MbK8lFZqFN2WsA== X-Received: by 2002:ac8:5a11:0:b0:35b:a2ec:2b73 with SMTP id n17-20020ac85a11000000b0035ba2ec2b73mr1063976qta.364.1663264993893; Thu, 15 Sep 2022 11:03:13 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id 79-20020a370452000000b006ce441816e0sm4314602qke.15.2022.09.15.11.03.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Sep 2022 11:03:13 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: 'mutable' within constexpr [PR92505] Date: Thu, 15 Sep 2022 14:03:12 -0400 Message-Id: <20220915180312.1596193-1-ppalka@redhat.com> X-Mailer: git-send-email 2.37.3.662.g36f8e7ed7d MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.4 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 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch permits accessing 'mutable' members of local objects during constexpr evaluation (which other compilers seem to accept in C++14 mode, while we reject), while continuing to reject it for global objects (as in the last line of cpp0x/constexpr-mutable1.C, which other compilers also reject). To distinguish between the two cases, it looks like we just need to additionally check CONSTRUCTOR_MUTABLE_POISION alongside DECL_MUTABLE_P in cxx_eval_component_reference before rejecting the access. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? PR c++/92505 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_component_reference): Test non_constant_p earlier. In C++14 or later, reject DECL_MUTABLE_P member accesses only if CONSTRUCTOR_MUTABLE_POISION is also set. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-mutable3.C: New test. * g++.dg/cpp1y/constexpr-mutable1.C: New test. --- gcc/cp/constexpr.cc | 11 +++++++---- gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C | 7 +++++++ gcc/testsuite/g++.dg/cpp1y/constexpr-mutable1.C | 16 ++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-mutable1.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 57283eabf3c..10639876d9c 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -4088,6 +4088,8 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, tree whole = cxx_eval_constant_expression (ctx, orig_whole, lval, non_constant_p, overflow_p); + if (*non_constant_p) + return t; if (INDIRECT_REF_P (whole) && integer_zerop (TREE_OPERAND (whole, 0))) { @@ -4108,20 +4110,21 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, whole, part, NULL_TREE); /* Don't VERIFY_CONSTANT here; we only want to check that we got a CONSTRUCTOR. */ - if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR) + if (TREE_CODE (whole) != CONSTRUCTOR) { if (!ctx->quiet) error ("%qE is not a constant expression", orig_whole); *non_constant_p = true; + return t; } - if (DECL_MUTABLE_P (part)) + if ((cxx_dialect < cxx14 || CONSTRUCTOR_MUTABLE_POISON (whole)) + && DECL_MUTABLE_P (part)) { if (!ctx->quiet) error ("mutable %qD is not usable in a constant expression", part); *non_constant_p = true; + return t; } - if (*non_constant_p) - return t; bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole)); FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value) { diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C new file mode 100644 index 00000000000..46c9d8437be --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C @@ -0,0 +1,7 @@ +// PR c++/92505 +// { dg-do compile { target c++11 } } + +struct A { mutable int m; }; +constexpr int f(A a) { return a.m; } +static_assert(f({42}) == 42, ""); +// { dg-error "non-constant|mutable" "" { target c++11_only } .-1 } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-mutable1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-mutable1.C new file mode 100644 index 00000000000..6c47988c01a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-mutable1.C @@ -0,0 +1,16 @@ +// PR c++/92505 +// { dg-do compile { target c++14 } } + +struct S { mutable int m; }; + +static_assert(S{42}.m == 42, ""); + +constexpr int f() { + S s = {40}; + s.m++; + const auto& cs = s; + ++cs.m; + return cs.m; +} + +static_assert(f() == 42, "");