diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-12-09 23:56:39 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-12-09 23:56:39 +0000 |
commit | 22600ff32878d72edf4eeb2c52139760fd443656 (patch) | |
tree | 01cbab831f32a58d215df1afef9fc57a4524a642 /llvm/lib/IR/Metadata.cpp | |
parent | 4cea5b4954e557c2e4c0ff5444952619d17defbd (diff) | |
download | bcm5719-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.cpp | 12 |
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) |