[llvm] r223858 - IR: Fix memory corruption in MDNode new/delete
Duncan P. N. Exon Smith
dexonsmith at apple.com
Tue Dec 9 15:56:39 PST 2014
Author: dexonsmith
Date: Tue Dec 9 17:56:39 2014
New Revision: 223858
URL: http://llvm.org/viewvc/llvm-project?rev=223858&view=rev
Log:
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.
Modified:
llvm/trunk/lib/IR/Metadata.cpp
Modified: llvm/trunk/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=223858&r1=223857&r2=223858&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Metadata.cpp (original)
+++ llvm/trunk/lib/IR/Metadata.cpp Tue Dec 9 17:56:39 2014
@@ -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)
More information about the llvm-commits
mailing list