aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Interp.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-06-18 14:37:29 +0200
committerGitHub <noreply@github.com>2025-06-18 14:37:29 +0200
commit7c15edb306932e41c159f3d69c161ed0d89d47b7 (patch)
treeb1b581d5c5e160486bb7786fde214343ceffd396 /clang/lib/AST/ByteCode/Interp.cpp
parent34a48941498d95ec2682f7adaeb6115b7b4d70ba (diff)
downloadllvm-7c15edb306932e41c159f3d69c161ed0d89d47b7.zip
llvm-7c15edb306932e41c159f3d69c161ed0d89d47b7.tar.gz
llvm-7c15edb306932e41c159f3d69c161ed0d89d47b7.tar.bz2
Reapply "[clang][bytecode] Allocate IntegralAP and Floating types usi… (#144676)
…ng an allocator (#144246)" This reverts commit 57828fec760f086b334ce0cb1c465fc559dcaea4.
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Interp.cpp106
1 files changed, 102 insertions, 4 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 5c8abff..1e2032f 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1935,8 +1935,10 @@ bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth))
return false;
- S.Stk.push<IntegralAP<false>>(
- IntegralAP<false>::from(Ptr.getIntegerRepresentation(), BitWidth));
+ auto Result = S.allocAP<IntegralAP<false>>(BitWidth);
+ Result.copy(APInt(BitWidth, Ptr.getIntegerRepresentation()));
+
+ S.Stk.push<IntegralAP<false>>(Result);
return true;
}
@@ -1946,8 +1948,10 @@ bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth))
return false;
- S.Stk.push<IntegralAP<true>>(
- IntegralAP<true>::from(Ptr.getIntegerRepresentation(), BitWidth));
+ auto Result = S.allocAP<IntegralAP<true>>(BitWidth);
+ Result.copy(APInt(BitWidth, Ptr.getIntegerRepresentation()));
+
+ S.Stk.push<IntegralAP<true>>(Result);
return true;
}
@@ -2053,6 +2057,100 @@ bool arePotentiallyOverlappingStringLiterals(const Pointer &LHS,
return Shorter == Longer.take_front(Shorter.size());
}
+static void copyPrimitiveMemory(InterpState &S, const Pointer &Ptr,
+ PrimType T) {
+
+ if (T == PT_IntAPS) {
+ auto &Val = Ptr.deref<IntegralAP<true>>();
+ if (!Val.singleWord()) {
+ uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()];
+ Val.take(NewMemory);
+ }
+ } else if (T == PT_IntAP) {
+ auto &Val = Ptr.deref<IntegralAP<false>>();
+ if (!Val.singleWord()) {
+ uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()];
+ Val.take(NewMemory);
+ }
+ } else if (T == PT_Float) {
+ auto &Val = Ptr.deref<Floating>();
+ if (!Val.singleWord()) {
+ uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()];
+ Val.take(NewMemory);
+ }
+ }
+}
+
+template <typename T>
+static void copyPrimitiveMemory(InterpState &S, const Pointer &Ptr) {
+ assert(needsAlloc<T>());
+ auto &Val = Ptr.deref<T>();
+ if (!Val.singleWord()) {
+ uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()];
+ Val.take(NewMemory);
+ }
+}
+
+static void finishGlobalRecurse(InterpState &S, const Pointer &Ptr) {
+ if (const Record *R = Ptr.getRecord()) {
+ for (const Record::Field &Fi : R->fields()) {
+ if (Fi.Desc->isPrimitive()) {
+ TYPE_SWITCH_ALLOC(Fi.Desc->getPrimType(), {
+ copyPrimitiveMemory<T>(S, Ptr.atField(Fi.Offset));
+ });
+ copyPrimitiveMemory(S, Ptr.atField(Fi.Offset), Fi.Desc->getPrimType());
+ } else
+ finishGlobalRecurse(S, Ptr.atField(Fi.Offset));
+ }
+ return;
+ }
+
+ if (const Descriptor *D = Ptr.getFieldDesc(); D && D->isArray()) {
+ unsigned NumElems = D->getNumElems();
+ if (NumElems == 0)
+ return;
+
+ if (D->isPrimitiveArray()) {
+ PrimType PT = D->getPrimType();
+ if (!needsAlloc(PT))
+ return;
+ assert(NumElems >= 1);
+ const Pointer EP = Ptr.atIndex(0);
+ bool AllSingleWord = true;
+ TYPE_SWITCH_ALLOC(PT, {
+ if (!EP.deref<T>().singleWord()) {
+ copyPrimitiveMemory<T>(S, EP);
+ AllSingleWord = false;
+ }
+ });
+ if (AllSingleWord)
+ return;
+ for (unsigned I = 1; I != D->getNumElems(); ++I) {
+ const Pointer EP = Ptr.atIndex(I);
+ copyPrimitiveMemory(S, EP, PT);
+ }
+ } else {
+ assert(D->isCompositeArray());
+ for (unsigned I = 0; I != D->getNumElems(); ++I) {
+ const Pointer EP = Ptr.atIndex(I).narrow();
+ finishGlobalRecurse(S, EP);
+ }
+ }
+ }
+}
+
+bool FinishInitGlobal(InterpState &S, CodePtr OpPC) {
+ const Pointer &Ptr = S.Stk.pop<Pointer>();
+
+ finishGlobalRecurse(S, Ptr);
+ if (Ptr.canBeInitialized()) {
+ Ptr.initialize();
+ Ptr.activate();
+ }
+
+ return true;
+}
+
// https://github.com/llvm/llvm-project/issues/102513
#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
#pragma optimize("", off)