aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/InterpState.cpp33
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;
+}