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 1E3023857BA2 for ; Thu, 15 Sep 2022 18:03:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1E3023857BA2 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1663265005; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=MjzA4rhsAOlMLRLXWiexiB8VEC3NpP4kcpUySOv7Kgc=; b=LoDnpuTbxb/o79cRAX/qeDneem0u1bYhodleIcKYoSZA4q1jW7Bwq/3augr9mgHPbBdMQL PwnJcQzJgzdFHJbI3p05H3TKVH6rG52q5xrNZjsyLUNEiryZi0mzqGpoPyC3xyD4usKMUX naLeX+X654C0Lp3OemrurF39ilNKryQ= 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) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka 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 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true 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 List-Id: 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, ""); -- 2.37.3.662.g36f8e7ed7d