diff options
Diffstat (limited to 'clang/lib/AST/ByteCode/InterpState.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/InterpState.cpp | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp index 7848f29..32ad07b 100644 --- a/clang/lib/AST/ByteCode/InterpState.cpp +++ b/clang/lib/AST/ByteCode/InterpState.cpp @@ -52,7 +52,7 @@ void InterpState::cleanup() { // As a last resort, make sure all pointers still pointing to a dead block // don't point to it anymore. for (DeadBlock *DB = DeadBlocks; DB; DB = DB->Next) { - for (Pointer *P = DB->B.Pointers; P; P = P->Next) { + for (Pointer *P = DB->B.Pointers; P; P = P->asBlockPointer().Next) { P->PointeeStorage.BS.Pointee = nullptr; } } @@ -77,27 +77,27 @@ void InterpState::deallocate(Block *B) { const Descriptor *Desc = B->getDescriptor(); assert(Desc); + // The block might have a pointer saved in a field in its data + // that points to the block itself. We call the dtor first, + // which will destroy all the data but leave InlineDescriptors + // intact. If the block THEN still has pointers, we create a + // DeadBlock for it. + if (B->IsInitialized) + B->invokeDtor(); + if (B->hasPointers()) { size_t Size = B->getSize(); - // Allocate a new block, transferring over pointers. char *Memory = reinterpret_cast<char *>(std::malloc(sizeof(DeadBlock) + Size)); auto *D = new (Memory) DeadBlock(DeadBlocks, B); - std::memset(D->B.rawData(), 0, D->B.getSize()); - - // Move data and metadata from the old block to the new (dead)block. - if (B->IsInitialized && Desc->MoveFn) { - Desc->MoveFn(B, B->data(), D->data(), Desc); - if (Desc->getMetadataSize() > 0) - std::memcpy(D->rawData(), B->rawData(), Desc->getMetadataSize()); - } + // Since the block doesn't hold any actual data anymore, we can just + // memcpy() everything over. + std::memcpy(D->rawData(), B->rawData(), Desc->getAllocSize()); D->B.IsInitialized = B->IsInitialized; // We moved the contents over to the DeadBlock. B->IsInitialized = false; - } else if (B->IsInitialized) { - B->invokeDtor(); } } |