diff options
| author | Timm Bäder <tbaeder@redhat.com> | 2024-07-24 17:56:39 +0200 |
|---|---|---|
| committer | Timm Bäder <tbaeder@redhat.com> | 2024-07-24 19:15:10 +0200 |
| commit | bb0300cf7ce54bfbb1607348c89cb0525e12076b (patch) | |
| tree | 0e4f96dfb7254b4cc5f9197627e48230d18c1dd9 | |
| parent | 8fd9624cf729dd722a170a9dfd8f725966515231 (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.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/AST/Interp/Compiler.h | 6 | ||||
| -rw-r--r-- | clang/test/AST/Interp/records.cpp | 19 |
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, ""); +} |
