[clang] [clang][bytecode] Mark CXXDefaultInitExprs in InitLink chain (PR #166395)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 4 08:06:39 PST 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/166395
So we know before _what_ entry in the chain we need to look for the InitList.
Fixes https://github.com/llvm/llvm-project/issues/166171
>From 7e589cbff35a0e3c5184932eaf7d04a549bab227 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 4 Nov 2025 16:48:51 +0100
Subject: [PATCH] [clang][bytecode] Mark CXXDefaultInitExprs in InitLink chain
So we know before _what_ entry in the chain we need to look for the
InitList.
Fixes https://github.com/llvm/llvm-project/issues/166171
---
clang/lib/AST/ByteCode/Compiler.cpp | 11 ++++++-----
clang/lib/AST/ByteCode/Compiler.h | 17 +++++++++++++----
clang/test/AST/ByteCode/cxx14.cpp | 21 +++++++++++++++++++++
3 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 6c088469a3ca2..09d22e3d79e5a 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5412,8 +5412,7 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
unsigned EndIndex = 0;
// Find the init list.
for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
- if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
- InitStack[StartIndex].Kind == InitLink::K_This) {
+ if (InitStack[StartIndex].Kind == InitLink::K_DIE) {
EndIndex = StartIndex;
--StartIndex;
break;
@@ -5426,7 +5425,8 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
continue;
if (InitStack[StartIndex].Kind != InitLink::K_Field &&
- InitStack[StartIndex].Kind != InitLink::K_Elem)
+ InitStack[StartIndex].Kind != InitLink::K_Elem &&
+ InitStack[StartIndex].Kind != InitLink::K_DIE)
break;
}
@@ -5437,7 +5437,8 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
// Emit the instructions.
for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
- if (InitStack[I].Kind == InitLink::K_InitList)
+ if (InitStack[I].Kind == InitLink::K_InitList ||
+ InitStack[I].Kind == InitLink::K_DIE)
continue;
if (!InitStack[I].template emit<Emitter>(this, E))
return false;
@@ -6306,8 +6307,8 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
unsigned FirstLinkOffset =
R->getField(cast<FieldDecl>(IFD->chain()[0]))->Offset;
- InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr));
InitLinkScope<Emitter> ILS(this, InitLink::Field(FirstLinkOffset));
+ InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr));
if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
IsUnion))
return false;
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index 5c46f75af4da3..0c6cab9276531 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -52,12 +52,14 @@ struct InitLink {
K_Decl = 3,
K_Elem = 5,
K_RVO = 6,
- K_InitList = 7
+ K_InitList = 7,
+ K_DIE = 8,
};
static InitLink This() { return InitLink{K_This}; }
static InitLink InitList() { return InitLink{K_InitList}; }
static InitLink RVO() { return InitLink{K_RVO}; }
+ static InitLink DIE() { return InitLink{K_DIE}; }
static InitLink Field(unsigned Offset) {
InitLink IL{K_Field};
IL.Offset = Offset;
@@ -668,22 +670,29 @@ template <class Emitter> class InitLinkScope final {
~InitLinkScope() { this->Ctx->InitStack.pop_back(); }
-private:
+public:
Compiler<Emitter> *Ctx;
};
template <class Emitter> class InitStackScope final {
public:
InitStackScope(Compiler<Emitter> *Ctx, bool Active)
- : Ctx(Ctx), OldValue(Ctx->InitStackActive) {
+ : Ctx(Ctx), OldValue(Ctx->InitStackActive), Active(Active) {
Ctx->InitStackActive = Active;
+ if (Active)
+ Ctx->InitStack.push_back(InitLink::DIE());
}
- ~InitStackScope() { this->Ctx->InitStackActive = OldValue; }
+ ~InitStackScope() {
+ this->Ctx->InitStackActive = OldValue;
+ if (Active)
+ Ctx->InitStack.pop_back();
+ }
private:
Compiler<Emitter> *Ctx;
bool OldValue;
+ bool Active;
};
} // namespace interp
diff --git a/clang/test/AST/ByteCode/cxx14.cpp b/clang/test/AST/ByteCode/cxx14.cpp
index 9622311e100cb..57cb42ea4a98b 100644
--- a/clang/test/AST/ByteCode/cxx14.cpp
+++ b/clang/test/AST/ByteCode/cxx14.cpp
@@ -7,3 +7,24 @@ constexpr int(*null_ptr)() = nullptr;
constexpr int test4 = (*null_ptr)(); // both-error {{must be initialized by a constant expression}} \
// both-note {{evaluates to a null function pointer}}
+struct E {
+ int n = 0;
+ struct {
+ void *x = this;
+ };
+ void *y = this;
+};
+constexpr E e1 = E();
+static_assert(e1.x != e1.y, "");
+constexpr E e2 = E{0};
+static_assert(e2.x != e2.y, "");
+
+struct S {
+ int &&a = 2;
+ int b[1]{a};
+};
+constexpr int foo() {
+ S s{12};
+ return s.b[0];
+}
+static_assert(foo() == 12, "");
More information about the cfe-commits
mailing list