https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/141006
Change the diagnostics when reading from the variable we're currently initializing do be the same as the one the current interpreter emits. >From 4a9c9a11f80de2306d07a836ec704aa6b3d7f35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Thu, 22 May 2025 06:52:09 +0200 Subject: [PATCH] [clang][bytecode] Change diagnostics for self-initialization Change the diagnostics when reading from the variable we're currently initializing do be the same as the one the current interpreter emits. --- clang/lib/AST/ByteCode/Interp.cpp | 15 +++++++++++++++ clang/test/AST/ByteCode/cxx11.cpp | 10 ++++++++++ clang/test/AST/ByteCode/cxx17.cpp | 9 +++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index fc61de9f92701..e3a08996ac65e 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -669,6 +669,21 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, if (const auto *VD = Ptr.getDeclDesc()->asVarDecl(); VD && (VD->isConstexpr() || VD->hasGlobalStorage())) { + + if (VD == S.EvaluatingDecl) { + if (!S.getLangOpts().CPlusPlus14 && + !VD->getType().isConstant(S.getASTContext())) { + // Diagnose as non-const read. + diagnoseNonConstVariable(S, OpPC, VD); + } else { + const SourceInfo &Loc = S.Current->getSource(OpPC); + // Diagnose as "read of object outside its lifetime". + S.FFDiag(Loc, diag::note_constexpr_access_uninit) + << AK << /*IsIndeterminate=*/false; + } + return false; + } + if (VD->getAnyInitializer()) { const SourceInfo &Loc = S.Current->getSource(OpPC); S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD; diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp index 368221106f640..44725f13e6a58 100644 --- a/clang/test/AST/ByteCode/cxx11.cpp +++ b/clang/test/AST/ByteCode/cxx11.cpp @@ -23,6 +23,16 @@ int array2[recurse2]; // both-warning {{variable length arrays in C++}} \ // expected-error {{variable length array declaration not allowed at file scope}} \ // ref-warning {{variable length array folded to constant array as an extension}} +constexpr int b = b; // both-error {{must be initialized by a constant expression}} \ + // both-note {{read of object outside its lifetime is not allowed in a constant expression}} + + +[[clang::require_constant_initialization]] int c = c; // both-error {{variable does not have a constant initializer}} \ + // both-note {{attribute here}} \ + // both-note {{read of non-const variable}} \ + // both-note {{declared here}} + + struct S { int m; }; diff --git a/clang/test/AST/ByteCode/cxx17.cpp b/clang/test/AST/ByteCode/cxx17.cpp index 9453906579f04..08a40e0a92862 100644 --- a/clang/test/AST/ByteCode/cxx17.cpp +++ b/clang/test/AST/ByteCode/cxx17.cpp @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s -// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s +// RUN: %clang_cc1 -std=c++17 -verify=expected,both %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s + +[[clang::require_constant_initialization]] int cc = cc; // both-error {{variable does not have a constant initializer}} \ + // both-note {{attribute here}} \ + // both-note {{ead of object outside its lifetime}} + struct F { int a; int b;}; constexpr F getF() { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits