summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimm Bäder <tbaeder@redhat.com>2024-07-24 17:56:39 +0200
committerTimm Bäder <tbaeder@redhat.com>2024-07-24 19:15:10 +0200
commitbb0300cf7ce54bfbb1607348c89cb0525e12076b (patch)
tree0e4f96dfb7254b4cc5f9197627e48230d18c1dd9
parent8fd9624cf729dd722a170a9dfd8f725966515231 (diff)
[clang][Interp] Fix initializing array subobjects with This pointers
We need to select the right array element once we see the CXXThisExpr.
-rw-r--r--clang/lib/AST/Interp/Compiler.cpp5
-rw-r--r--clang/lib/AST/Interp/Compiler.h6
-rw-r--r--clang/test/AST/Interp/records.cpp19
3 files changed, 30 insertions, 0 deletions
diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index 58a0852aca75..4d5d725d6964 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -89,6 +89,10 @@ bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
return Ctx->emitGetPtrLocal(Offset, E);
case K_Decl:
return Ctx->visitDeclRef(D, E);
+ case K_Elem:
+ if (!Ctx->emitConstUint32(Offset, E))
+ return false;
+ return Ctx->emitArrayElemPtrUint32(E);
default:
llvm_unreachable("Unhandled InitLink kind");
}
@@ -1556,6 +1560,7 @@ bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex,
return this->emitInitElem(*T, ElemIndex, Init);
}
+ InitLinkScope<Emitter> ILS(this, InitLink::Elem(ElemIndex));
// Advance the pointer currently on the stack to the given
// dimension.
if (!this->emitConstUint32(ElemIndex, Init))
diff --git a/clang/lib/AST/Interp/Compiler.h b/clang/lib/AST/Interp/Compiler.h
index 084f5aef25f8..d22b29d29a92 100644
--- a/clang/lib/AST/Interp/Compiler.h
+++ b/clang/lib/AST/Interp/Compiler.h
@@ -50,6 +50,7 @@ public:
K_Field = 1,
K_Temp = 2,
K_Decl = 3,
+ K_Elem = 5,
};
static InitLink This() { return InitLink{K_This}; }
@@ -68,6 +69,11 @@ public:
IL.D = D;
return IL;
}
+ static InitLink Elem(unsigned Index) {
+ InitLink IL{K_Elem};
+ IL.Offset = Index;
+ return IL;
+ }
InitLink(uint8_t Kind) : Kind(Kind) {}
template <class Emitter>
diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp
index 2fc88a0b1df6..d77e5a5c782c 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1537,3 +1537,22 @@ namespace BitSet {
Bitset()
};
}
+
+namespace ArrayInitChain {
+ struct StringLiteral {
+ const char *S;
+ };
+
+ struct CustomOperandVal {
+ StringLiteral Str;
+ unsigned Width;
+ unsigned Mask = Width + 1;
+ };
+
+ constexpr CustomOperandVal A[] = {
+ {},
+ };
+ static_assert(A[0].Str.S == nullptr, "");
+ static_assert(A[0].Width == 0, "");
+ static_assert(A[0].Mask == 1, "");
+}