[clang] [clang][bytecode] Mark global decls with diagnostics invalid (PR #122895)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 14 04:39:14 PST 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/122895
Even if their evaluation succeeds, mark them as invalid. This fixes some long standing differences to the ast walker interpeter.
>From 66c1a54bf96661aa0e5b60cf121b03776a8dcbbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 14 Jan 2025 13:16:31 +0100
Subject: [PATCH] [clang][bytecode] Mark global decls with diagnostics invalid
Even if their evaluation succeeds, mark them as invalid. This fixes
some long standing differences to the ast walker interpeter.
---
clang/lib/AST/ByteCode/EvalEmitter.cpp | 12 ++++++++++++
clang/test/AST/ByteCode/arrays.cpp | 15 +++++++--------
clang/test/AST/ByteCode/cxx23.cpp | 9 +++------
3 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index 9763fe89b73742..f9220e89abbc85 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -71,6 +71,18 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
if (!this->visitDeclAndReturn(VD, S.inConstantContext()))
EvalResult.setInvalid();
+ // Mark global variables as invalid if any diagnostic was produced.
+ if (S.hasPriorDiagnostic() && Context::shouldBeGloballyIndexed(VD)) {
+ if (auto GlobalIndex = P.getGlobal(VD)) {
+ Block *GlobalBlock = P.getGlobal(*GlobalIndex);
+ GlobalInlineDescriptor &GD =
+ *reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
+ GD.InitState = GlobalInitState::InitializerFailed;
+ if (GlobalBlock->isInitialized())
+ GlobalBlock->invokeDtor();
+ }
+ }
+
S.EvaluatingDecl = nullptr;
updateGlobalTemporaries();
return std::move(this->EvalResult);
diff --git a/clang/test/AST/ByteCode/arrays.cpp b/clang/test/AST/ByteCode/arrays.cpp
index 4097c65f7c6fba..297894659ff199 100644
--- a/clang/test/AST/ByteCode/arrays.cpp
+++ b/clang/test/AST/ByteCode/arrays.cpp
@@ -402,14 +402,13 @@ namespace NoInitMapLeak {
constexpr int a[] = {1,2,3,4/0,5}; // both-error {{must be initialized by a constant expression}} \
// both-note {{division by zero}} \
- // ref-note {{declared here}}
-
- /// FIXME: This should fail in the new interpreter as well.
- constexpr int b = a[0]; // ref-error {{must be initialized by a constant expression}} \
- // ref-note {{is not a constant expression}} \
- // ref-note {{declared here}}
- static_assert(b == 1, ""); // ref-error {{not an integral constant expression}} \
- // ref-note {{not a constant expression}}
+ // both-note {{declared here}}
+
+ constexpr int b = a[0]; // both-error {{must be initialized by a constant expression}} \
+ // both-note {{is not a constant expression}} \
+ // both-note {{declared here}}
+ static_assert(b == 1, ""); // both-error {{not an integral constant expression}} \
+ // both-note {{not a constant expression}}
constexpr int f() { // both-error {{never produces a constant expression}}
int a[] = {19,2,3/0,4}; // both-note 2{{division by zero}} \
diff --git a/clang/test/AST/ByteCode/cxx23.cpp b/clang/test/AST/ByteCode/cxx23.cpp
index 6a62ac11cde792..5c437c2eef84bf 100644
--- a/clang/test/AST/ByteCode/cxx23.cpp
+++ b/clang/test/AST/ByteCode/cxx23.cpp
@@ -217,16 +217,13 @@ namespace UndefinedThreeWay {
// all-note {{undefined function 'operator<=>' cannot be used in a constant expression}}
}
-/// FIXME: The new interpreter is missing the "initializer of q is not a constant expression" diagnostics.a
-/// That's because the cast from void* to int* is considered fine, but diagnosed. So we don't consider
-/// q to be uninitialized.
namespace VoidCast {
constexpr void* p = nullptr;
constexpr int* q = static_cast<int*>(p); // all-error {{must be initialized by a constant expression}} \
// all-note {{cast from 'void *' is not allowed in a constant expression}} \
- // ref-note {{declared here}}
- static_assert(q == nullptr); // ref-error {{not an integral constant expression}} \
- // ref-note {{initializer of 'q' is not a constant expression}}
+ // all-note {{declared here}}
+ static_assert(q == nullptr); // all-error {{not an integral constant expression}} \
+ // all-note {{initializer of 'q' is not a constant expression}}
}
namespace ExplicitLambdaInstancePointer {
More information about the cfe-commits
mailing list