https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/204824
…riable And diagnose it as a modification and not a read if applicable. >From 8f27571ff75fd6825d6ccfc66df6f71014fa3295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Fri, 19 Jun 2026 15:20:02 +0200 Subject: [PATCH] [clang][bytecode] Take AccessKinds into account in diagnoseNonConstVariable And diagnose it as a modification and not a read if applicable. --- clang/lib/AST/ByteCode/Interp.cpp | 24 +++++++++++++++++------- clang/test/AST/ByteCode/cxx20.cpp | 5 +++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 60914a2da111a..b022d71ae1e49 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -97,9 +97,10 @@ static void noteValueLocation(InterpState &S, const Block *B) { } static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC, - const ValueDecl *VD); + const ValueDecl *VD, + AccessKinds AK = AK_Read); static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC, - const ValueDecl *D) { + const ValueDecl *D, AccessKinds AK = AK_Read) { // This function tries pretty hard to produce a good diagnostic. Just skip // that if nobody will see it anyway. if (!S.diagnosing()) @@ -129,7 +130,7 @@ static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC, } if (!D->getType().isConstQualified()) { - diagnoseNonConstVariable(S, OpPC, D); + diagnoseNonConstVariable(S, OpPC, D, AK); } else if (const auto *VD = dyn_cast<VarDecl>(D)) { if (!VD->getAnyInitializer()) { diagnoseMissingInitializer(S, OpPC, VD); @@ -143,8 +144,13 @@ static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC, return false; } +static bool isModification(AccessKinds AK) { + return AK == AK_Assign || AK == AK_Increment || AK == AK_Decrement || + AK == AK_Construct || AK == AK_Destroy; +} + static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC, - const ValueDecl *VD) { + const ValueDecl *VD, AccessKinds AK) { if (!S.diagnosing()) return; @@ -168,8 +174,12 @@ static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC, return; if (VD->getType()->isIntegralOrEnumerationType()) { - S.FFDiag(Loc, diag::note_constexpr_ltor_non_const_int, 1) << VD; - S.Note(VD->getLocation(), diag::note_declared_at); + if (isModification(AK)) { + S.FFDiag(Loc, diag::note_constexpr_modify_global); + } else { + S.FFDiag(Loc, diag::note_constexpr_ltor_non_const_int, 1) << VD; + S.Note(VD->getLocation(), diag::note_declared_at); + } return; } @@ -1266,7 +1276,7 @@ bool CheckDummy(InterpState &S, CodePtr OpPC, const Block *B, AccessKinds AK) { return false; if (AK == AK_Read || AK == AK_Increment || AK == AK_Decrement) - return diagnoseUnknownDecl(S, OpPC, D); + return diagnoseUnknownDecl(S, OpPC, D, AK); if (AK == AK_Destroy || S.getLangOpts().CPlusPlus14) { const SourceInfo &E = S.Current->getSource(OpPC); diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp index a6409d4a2c268..7ff70076ee6e4 100644 --- a/clang/test/AST/ByteCode/cxx20.cpp +++ b/clang/test/AST/ByteCode/cxx20.cpp @@ -1,6 +1,11 @@ // RUN: %clang_cc1 -fcxx-exceptions -std=c++20 -verify=both,expected -fcxx-exceptions %s -DNEW_INTERP -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -fcxx-exceptions -std=c++20 -verify=both,ref -fcxx-exceptions %s + +int x; +static_assert(++x, "test"); // both-error {{not an integral constant expression}} \ + // both-note {{cannot modify an object that is visible outside that expression}} + void test_alignas_operand() { alignas(8) char dummy; static_assert(__alignof(dummy) == 8); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
