summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Metadata.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-09 23:56:39 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-09 23:56:39 +0000
commit22600ff32878d72edf4eeb2c52139760fd443656 (patch)
tree01cbab831f32a58d215df1afef9fc57a4524a642 /llvm/lib/IR/Metadata.cpp
parent4cea5b4954e557c2e4c0ff5444952619d17defbd (diff)
downloadbcm5719-llvm-22600ff32878d72edf4eeb2c52139760fd443656.tar.gz
bcm5719-llvm-22600ff32878d72edf4eeb2c52139760fd443656.zip
IR: Fix memory corruption in MDNode new/delete
There were two major problems with `MDNode` memory management. 1. `MDNode::operator new()` called a placement array constructor for `MDOperand`. What? Each operand needs to be placed individually. 2. `MDNode::operator delete()` failed to destruct the `MDOperand`s at all. Frankly it's hard to understand how this worked locally, how this survived an LTO bootstrap, or how it worked on most of the bots. llvm-svn: 223858
Diffstat (limited to 'llvm/lib/IR/Metadata.cpp')
-rw-r--r--llvm/lib/IR/Metadata.cpp12
1 files changed, 8 insertions, 4 deletions
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 7a354c42c4c..0f748495261 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -378,14 +378,18 @@ StringRef MDString::getString() const {
void *MDNode::operator new(size_t Size, unsigned NumOps) {
void *Ptr = ::operator new(Size + NumOps * sizeof(MDOperand));
- MDOperand *First = new (Ptr) MDOperand[NumOps];
- return First + NumOps;
+ MDOperand *O = static_cast<MDOperand *>(Ptr);
+ for (MDOperand *E = O + NumOps; O != E; ++O)
+ (void)new (O) MDOperand;
+ return O;
}
void MDNode::operator delete(void *Mem) {
MDNode *N = static_cast<MDNode *>(Mem);
- MDOperand *Last = static_cast<MDOperand *>(Mem);
- ::operator delete(Last - N->NumOperands);
+ MDOperand *O = static_cast<MDOperand *>(Mem);
+ for (MDOperand *E = O - N->NumOperands; O != E; --O)
+ (O - 1)->~MDOperand();
+ ::operator delete(O);
}
MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs)
OpenPOWER on IntegriCloud