summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Metadata.cpp
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2015-06-17 01:21:20 +0000
committerJames Y Knight <jyknight@google.com>2015-06-17 01:21:20 +0000
commit8096d34e5f14cc4ba65a052376459d714b995795 (patch)
treeba5e6e2cef6279f58ecfc981bb78f6ab9a756bd2 /llvm/lib/IR/Metadata.cpp
parent456baad24d620e2e1feb39436ef861491cca2736 (diff)
downloadbcm5719-llvm-8096d34e5f14cc4ba65a052376459d714b995795.tar.gz
bcm5719-llvm-8096d34e5f14cc4ba65a052376459d714b995795.zip
Fix alignment issues in LLVM.
Adds static_asserts to ensure alignment of concatenated objects is correct, and fixes them where they are not. Also changes the definition of AlignOf to use constexpr, except on MSVC, to avoid enum comparison warnings from GCC. (There's not too much of this in llvm itself, most of the fun is in clang). This seems to make LLVM actually work without Bus Error on 32bit sparc. Differential Revision: http://reviews.llvm.org/D10271 llvm-svn: 239872
Diffstat (limited to 'llvm/lib/IR/Metadata.cpp')
-rw-r--r--llvm/lib/IR/Metadata.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 75b4046ef44..de1587d28a0 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -381,20 +381,35 @@ StringRef MDString::getString() const {
// MDNode implementation.
//
+// Assert that the MDNode types will not be unaligned by the objects
+// prepended to them.
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ static_assert(llvm::AlignOf<uint64_t>::Alignment >= \
+ llvm::AlignOf<CLASS>::Alignment, \
+ "Alignment sufficient after objects prepended to " #CLASS);
+#include "llvm/IR/Metadata.def"
+
void *MDNode::operator new(size_t Size, unsigned NumOps) {
- void *Ptr = ::operator new(Size + NumOps * sizeof(MDOperand));
+ size_t OpSize = NumOps * sizeof(MDOperand);
+ // uint64_t is the most aligned type we need support (ensured by static_assert
+ // above)
+ OpSize = RoundUpToAlignment(OpSize, llvm::alignOf<uint64_t>());
+ void *Ptr = reinterpret_cast<char *>(::operator new(OpSize + Size)) + OpSize;
MDOperand *O = static_cast<MDOperand *>(Ptr);
- for (MDOperand *E = O + NumOps; O != E; ++O)
- (void)new (O) MDOperand;
- return O;
+ for (MDOperand *E = O - NumOps; O != E; --O)
+ (void)new (O - 1) MDOperand;
+ return Ptr;
}
void MDNode::operator delete(void *Mem) {
MDNode *N = static_cast<MDNode *>(Mem);
+ size_t OpSize = N->NumOperands * sizeof(MDOperand);
+ OpSize = RoundUpToAlignment(OpSize, llvm::alignOf<uint64_t>());
+
MDOperand *O = static_cast<MDOperand *>(Mem);
for (MDOperand *E = O - N->NumOperands; O != E; --O)
(O - 1)->~MDOperand();
- ::operator delete(O);
+ ::operator delete(reinterpret_cast<char *>(Mem) - OpSize);
}
MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
OpenPOWER on IntegriCloud