From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1888) id 110F038197C9; Fri, 16 Sep 2022 15:11:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 110F038197C9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663341091; bh=SPt5vRYLV4dhTToRKiMdtmONeKxxjOMepRErVGbEAA0=; h=From:To:Subject:Date:From; b=f0i3tas1jP2eUzv0OTuah1q3ag3kTQLYoHFmuUYKK7CfsIS024D1yDyeVvZQFEuiy 1Q2+i2Z2xgO+FIDP0V8io49uKWn2/J7Jr4daHX9NRHJnlsTORyxXkWXTkSJjm5mszP WlMHVL7hQmacsPWtIvQ3CEOHCan6Yc4OneubIOhE= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Patrick Palka To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-2701] c++: 'mutable' member within constexpr [PR92505] X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/master X-Git-Oldrev: b6adc6255f527edd50c08c4aacb4ee21df1c349c X-Git-Newrev: 7107ea6fb933f1e928593c7e92edfd64ccf0df63 Message-Id: <20220916151131.110F038197C9@sourceware.org> Date: Fri, 16 Sep 2022 15:11:31 +0000 (GMT) List-Id: https://gcc.gnu.org/g:7107ea6fb933f1e928593c7e92edfd64ccf0df63 commit r13-2701-g7107ea6fb933f1e928593c7e92edfd64ccf0df63 Author: Patrick Palka Date: Fri Sep 16 11:10:43 2022 -0400 c++: 'mutable' member within constexpr [PR92505] This patch permits accessing 'mutable' members of local objects during constexpr evaluation, while continuing to reject it for global objects (as in the last line of cpp0x/constexpr-mutable1.C). To distinguish between the two cases, it looks like it suffices to just check CONSTRUCTOR_MUTABLE_POSION in cxx_eval_component_reference before deciding to reject a DECL_MUTABLE_P member access. PR c++/92505 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_component_reference): Check non_constant_p sooner. In C++14 or later, reject a DECL_MUTABLE_P member access 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. Diff: --- gcc/cp/constexpr.cc | 11 +++++++---- gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C | 9 +++++++++ gcc/testsuite/g++.dg/cpp1y/constexpr-mutable1.C | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) 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..51499fac520 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C @@ -0,0 +1,9 @@ +// 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, "");