diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp b/contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp index 2cb87ef07fe5..4ea05305540e 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp +++ b/contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp @@ -33,6 +33,18 @@ InterpState::~InterpState() { } } +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) { + P->PointeeStorage.BS.Pointee = nullptr; + } + } + + Alloc.cleanup(); +} + Frame *InterpState::getCurrentFrame() { if (Current && Current->Caller) return Current; @@ -57,17 +69,34 @@ void InterpState::deallocate(Block *B) { 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 (Desc->MoveFn) { + 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()); } + D->B.IsInitialized = B->IsInitialized; // We moved the contents over to the DeadBlock. B->IsInitialized = false; - } else { + } else if (B->IsInitialized) { B->invokeDtor(); } } + +bool InterpState::maybeDiagnoseDanglingAllocations() { + bool NoAllocationsLeft = (Alloc.getNumAllocations() == 0); + + if (!checkingPotentialConstantExpression()) { + for (const auto &It : Alloc.allocation_sites()) { + assert(It.second.size() > 0); + + const Expr *Source = It.first; + CCEDiag(Source->getExprLoc(), diag::note_constexpr_memory_leak) + << (It.second.size() - 1) << Source->getSourceRange(); + } + } + return NoAllocationsLeft; +} |