https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/205820
The instance pointer being mutable is perfectly fine, we just can't read anything from it. This regresses a test case in `cxx11.cpp` where we now diagnose an extra frame for `U(g1.u)`, but this seems correct since the read is happening in the copy constructor of `U`. >From 64b49b225f33298caa1dbb9070c3713da8077f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Thu, 25 Jun 2026 13:59:40 +0200 Subject: [PATCH] asdf --- clang/lib/AST/ByteCode/Interp.cpp | 20 +++++++------------- clang/test/AST/ByteCode/cxx11.cpp | 1 + clang/test/AST/ByteCode/mutable.cpp | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 71021815baeef..2f09c19178f09 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -660,16 +660,7 @@ bool CheckMutable(InterpState &S, CodePtr OpPC, PtrView Ptr, AccessKinds AK) { if (S.checkingConstantDestruction()) { // Never allowed when checking for constant destruction. - // Find the reason this pointer is mutable. - PtrView MutablePtr = Ptr; - while (!MutablePtr.isRoot() && MutablePtr.getBase().isMutable()) - MutablePtr = MutablePtr.getBase(); - - const FieldDecl *Field = MutablePtr.getField(); - S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_mutable, 1) - << AK << Field; - S.Note(Field->getLocation(), diag::note_declared_at); - return false; + // Diagnose below. } else if (S.getLangOpts().CPlusPlus14 && S.lifetimeStartedInEvaluation(Ptr.block())) { // In C++14 onwards, it is permitted to read a mutable member whose @@ -677,8 +668,13 @@ bool CheckMutable(InterpState &S, CodePtr OpPC, PtrView Ptr, AccessKinds AK) { return true; } + // Find the reason this pointer is mutable. + PtrView MutablePtr = Ptr; + while (!MutablePtr.isRoot() && MutablePtr.getBase().isMutable()) + MutablePtr = MutablePtr.getBase(); + const SourceInfo &Loc = S.Current->getSource(OpPC); - const FieldDecl *Field = Ptr.getField(); + const FieldDecl *Field = MutablePtr.getField(); S.FFDiag(Loc, diag::note_constexpr_access_mutable, 1) << AK << Field; S.Note(Field->getLocation(), diag::note_declared_at); return false; @@ -1025,8 +1021,6 @@ static bool CheckInvoke(InterpState &S, CodePtr OpPC, const Pointer &Ptr, return false; if (!(IsCtor || IsDtor) && !CheckLifetime(S, OpPC, Ptr, AK_MemberCall)) return false; - if (!IsDtor && !CheckMutable(S, OpPC, Ptr)) - return false; } return true; } diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp index ffe2f3c67c511..3553ab3ba68ad 100644 --- a/clang/test/AST/ByteCode/cxx11.cpp +++ b/clang/test/AST/ByteCode/cxx11.cpp @@ -343,6 +343,7 @@ namespace ReadMutableInCopyCtor { constexpr G g1 = {}; constexpr G g2 = g1; // both-error {{must be initialized by a constant expression}} \ // both-note {{read of mutable member 'u'}} \ + // expected-note {{in call to 'U(g1.u)'}} \ // both-note {{in call to 'G(g1)'}} } diff --git a/clang/test/AST/ByteCode/mutable.cpp b/clang/test/AST/ByteCode/mutable.cpp index 16c8ce9125d5e..5dbaa66ab4c86 100644 --- a/clang/test/AST/ByteCode/mutable.cpp +++ b/clang/test/AST/ByteCode/mutable.cpp @@ -73,4 +73,27 @@ constexpr D d2 = d1; // both-error {{must be initialized by a constant expressio // both-note {{read of mutable member 'y}} \ // both-note {{in call to}} +namespace MutablenessFromBasePtr { + struct Foo { + constexpr int five() const { return 5; } + int k = 12; + }; + struct M { + mutable Foo F; // both-note {{declared here}} + }; + constexpr M m{}; + static_assert(m.F.k == 12, ""); // both-error {{not an integral constant expression}} \ + // both-note {{read of mutable member 'F' is not allowed in a constant expression}} +} +namespace MemberCall { + struct Foo { + constexpr int five() const { return 5; } + }; + struct M { + mutable Foo F; + constexpr int zomg() const { return F.five(); } + }; + constexpr M m{}; + static_assert(m.zomg() == 5, ""); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
