Path: blob/main/contrib/llvm-project/clang/lib/AST/ByteCode/DynamicAllocator.cpp
213799 views
//==-------- DynamicAllocator.cpp - Dynamic allocations ----------*- C++ -*-==//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "DynamicAllocator.h"9#include "InterpBlock.h"10#include "InterpState.h"1112using namespace clang;13using namespace clang::interp;1415DynamicAllocator::~DynamicAllocator() { cleanup(); }1617void DynamicAllocator::cleanup() {18// Invoke destructors of all the blocks and as a last restort,19// reset all the pointers pointing to them to null pointees.20// This should never show up in diagnostics, but it's necessary21// for us to not cause use-after-free problems.22for (auto &Iter : AllocationSites) {23auto &AllocSite = Iter.second;24for (auto &Alloc : AllocSite.Allocations) {25Block *B = reinterpret_cast<Block *>(Alloc.Memory.get());26B->invokeDtor();27if (B->hasPointers()) {28while (B->Pointers) {29Pointer *Next = B->Pointers->Next;30B->Pointers->PointeeStorage.BS.Pointee = nullptr;31B->Pointers = Next;32}33B->Pointers = nullptr;34}35}36}3738AllocationSites.clear();39}4041Block *DynamicAllocator::allocate(const Expr *Source, PrimType T,42size_t NumElements, unsigned EvalID,43Form AllocForm) {44// Create a new descriptor for an array of the specified size and45// element type.46const Descriptor *D = allocateDescriptor(47Source, T, Descriptor::InlineDescMD, NumElements, /*IsConst=*/false,48/*IsTemporary=*/false, /*IsMutable=*/false);4950return allocate(D, EvalID, AllocForm);51}5253Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,54size_t NumElements, unsigned EvalID,55Form AllocForm) {56assert(ElementDesc->getMetadataSize() == 0);57// Create a new descriptor for an array of the specified size and58// element type.59// FIXME: Pass proper element type.60const Descriptor *D = allocateDescriptor(61ElementDesc->asExpr(), nullptr, ElementDesc, Descriptor::InlineDescMD,62NumElements,63/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);64return allocate(D, EvalID, AllocForm);65}6667Block *DynamicAllocator::allocate(const Descriptor *D, unsigned EvalID,68Form AllocForm) {69assert(D);70assert(D->asExpr());7172auto Memory =73std::make_unique<std::byte[]>(sizeof(Block) + D->getAllocSize());74auto *B = new (Memory.get()) Block(EvalID, D, /*isStatic=*/false);75B->invokeCtor();7677assert(D->getMetadataSize() == sizeof(InlineDescriptor));78InlineDescriptor *ID = reinterpret_cast<InlineDescriptor *>(B->rawData());79ID->Desc = D;80ID->IsActive = true;81ID->Offset = sizeof(InlineDescriptor);82ID->IsBase = false;83ID->IsFieldMutable = false;84ID->IsConst = false;85ID->IsInitialized = false;86ID->IsVolatile = false;8788if (D->isCompositeArray())89ID->LifeState = Lifetime::Started;90else91ID->LifeState =92AllocForm == Form::Operator ? Lifetime::Ended : Lifetime::Started;9394B->IsDynamic = true;9596if (auto It = AllocationSites.find(D->asExpr()); It != AllocationSites.end())97It->second.Allocations.emplace_back(std::move(Memory));98else99AllocationSites.insert(100{D->asExpr(), AllocationSite(std::move(Memory), AllocForm)});101return B;102}103104bool DynamicAllocator::deallocate(const Expr *Source,105const Block *BlockToDelete, InterpState &S) {106auto It = AllocationSites.find(Source);107if (It == AllocationSites.end())108return false;109110auto &Site = It->second;111assert(Site.size() > 0);112113// Find the Block to delete.114auto AllocIt = llvm::find_if(Site.Allocations, [&](const Allocation &A) {115const Block *B = reinterpret_cast<const Block *>(A.Memory.get());116return BlockToDelete == B;117});118119assert(AllocIt != Site.Allocations.end());120121Block *B = reinterpret_cast<Block *>(AllocIt->Memory.get());122B->invokeDtor();123124S.deallocate(B);125Site.Allocations.erase(AllocIt);126127if (Site.size() == 0)128AllocationSites.erase(It);129130return true;131}132133134