Skip to content

Commit c1de9b9

Browse files
authored
[clang][bytecode] Mark global decls with diagnostics invalid (#122895)
Even if their evaluation succeeds, mark them as invalid. This fixes some long standing differences to the ast walker interpeter.
1 parent 8f6867c commit c1de9b9

File tree

3 files changed

+22
-14
lines changed

3 files changed

+22
-14
lines changed

clang/lib/AST/ByteCode/EvalEmitter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
7171
if (!this->visitDeclAndReturn(VD, S.inConstantContext()))
7272
EvalResult.setInvalid();
7373

74+
// Mark global variables as invalid if any diagnostic was produced.
75+
if (S.hasPriorDiagnostic() && Context::shouldBeGloballyIndexed(VD)) {
76+
if (auto GlobalIndex = P.getGlobal(VD)) {
77+
Block *GlobalBlock = P.getGlobal(*GlobalIndex);
78+
GlobalInlineDescriptor &GD =
79+
*reinterpret_cast<GlobalInlineDescriptor *>(GlobalBlock->rawData());
80+
GD.InitState = GlobalInitState::InitializerFailed;
81+
if (GlobalBlock->isInitialized())
82+
GlobalBlock->invokeDtor();
83+
}
84+
}
85+
7486
S.EvaluatingDecl = nullptr;
7587
updateGlobalTemporaries();
7688
return std::move(this->EvalResult);

clang/test/AST/ByteCode/arrays.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -402,14 +402,13 @@ namespace NoInitMapLeak {
402402

403403
constexpr int a[] = {1,2,3,4/0,5}; // both-error {{must be initialized by a constant expression}} \
404404
// both-note {{division by zero}} \
405-
// ref-note {{declared here}}
406-
407-
/// FIXME: This should fail in the new interpreter as well.
408-
constexpr int b = a[0]; // ref-error {{must be initialized by a constant expression}} \
409-
// ref-note {{is not a constant expression}} \
410-
// ref-note {{declared here}}
411-
static_assert(b == 1, ""); // ref-error {{not an integral constant expression}} \
412-
// ref-note {{not a constant expression}}
405+
// both-note {{declared here}}
406+
407+
constexpr int b = a[0]; // both-error {{must be initialized by a constant expression}} \
408+
// both-note {{is not a constant expression}} \
409+
// both-note {{declared here}}
410+
static_assert(b == 1, ""); // both-error {{not an integral constant expression}} \
411+
// both-note {{not a constant expression}}
413412

414413
constexpr int f() { // both-error {{never produces a constant expression}}
415414
int a[] = {19,2,3/0,4}; // both-note 2{{division by zero}} \

clang/test/AST/ByteCode/cxx23.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,16 +217,13 @@ namespace UndefinedThreeWay {
217217
// all-note {{undefined function 'operator<=>' cannot be used in a constant expression}}
218218
}
219219

220-
/// FIXME: The new interpreter is missing the "initializer of q is not a constant expression" diagnostics.a
221-
/// That's because the cast from void* to int* is considered fine, but diagnosed. So we don't consider
222-
/// q to be uninitialized.
223220
namespace VoidCast {
224221
constexpr void* p = nullptr;
225222
constexpr int* q = static_cast<int*>(p); // all-error {{must be initialized by a constant expression}} \
226223
// all-note {{cast from 'void *' is not allowed in a constant expression}} \
227-
// ref-note {{declared here}}
228-
static_assert(q == nullptr); // ref-error {{not an integral constant expression}} \
229-
// ref-note {{initializer of 'q' is not a constant expression}}
224+
// all-note {{declared here}}
225+
static_assert(q == nullptr); // all-error {{not an integral constant expression}} \
226+
// all-note {{initializer of 'q' is not a constant expression}}
230227
}
231228

232229
namespace ExplicitLambdaInstancePointer {

0 commit comments

Comments
 (0)