aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlisdair Meredith <public@alisdairm.net>2009-07-09 17:26:16 +0000
committerAlisdair Meredith <public@alisdairm.net>2009-07-09 17:26:16 +0000
commitab86c57972c5b3c19d3da737c05b0fa6f5c1b11a (patch)
tree3d4cd52f743497033bca8665bf55ee9545321d96
parent18359229ccd89907441a5a78aad433ec984ae9b9 (diff)
downloadexternal_llvm-ab86c57972c5b3c19d3da737c05b0fa6f5c1b11a.zip
external_llvm-ab86c57972c5b3c19d3da737c05b0fa6f5c1b11a.tar.gz
external_llvm-ab86c57972c5b3c19d3da737c05b0fa6f5c1b11a.tar.bz2
Resolve undefined behaviour when ManagedStatic is instantiated with a fixed-length array type.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75149 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Support/ManagedStatic.h18
1 files changed, 10 insertions, 8 deletions
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 4fc6483..b8e2235 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -27,10 +27,12 @@ void* object_creator() {
/// object_deleter - Helper method for ManagedStatic.
///
-template<class C>
-void object_deleter(void *Ptr) {
- delete (C*)Ptr;
-}
+template<typename T> struct object_deleter {
+ static void call(void * Ptr) { delete (T*)Ptr; }
+};
+template<typename T, size_t N> struct object_deleter<T[N]> {
+ static void call(void * Ptr) { delete[] (T*)Ptr; }
+};
/// ManagedStaticBase - Common base class for ManagedStatic instances.
class ManagedStaticBase {
@@ -62,28 +64,28 @@ public:
C &operator*() {
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
return *static_cast<C*>(Ptr);
}
C *operator->() {
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
return static_cast<C*>(Ptr);
}
const C &operator*() const {
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
return *static_cast<C*>(Ptr);
}
const C *operator->() const {
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
return static_cast<C*>(Ptr);
}