ICU-20271 Use C++11 operator new = delete to disallow heap allocation.

This commit is contained in:
Fredrik Roubert 2018-11-15 14:01:42 +01:00 committed by Fredrik Roubert
parent 6c781b1428
commit 2d3901ae5d
4 changed files with 33 additions and 38 deletions

View file

@ -290,6 +290,13 @@ inline T *LocalMemory<T>::allocateInsteadAndCopy(int32_t newCapacity, int32_t le
template<typename T, int32_t stackCapacity>
class MaybeStackArray {
public:
// No heap allocation. Use only on the stack.
static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
static void* U_EXPORT2 operator new[](size_t) U_NO_THROW = delete;
#if U_HAVE_PLACEMENT_NEW
static void* U_EXPORT2 operator new(size_t, void*) U_NO_THROW = delete;
#endif
/**
* Default constructor initializes with internal T[stackCapacity] buffer.
*/
@ -402,20 +409,6 @@ private:
/* No ownership transfer: No copy constructor, no assignment operator. */
MaybeStackArray(const MaybeStackArray & /*other*/) {}
void operator=(const MaybeStackArray & /*other*/) {}
// No heap allocation. Use only on the stack.
// (Declaring these functions private triggers a cascade of problems:
// MSVC insists on exporting an instantiation of MaybeStackArray, which
// requires that all functions be defined.
// An empty implementation of new() is rejected, it must return a value.
// Returning NULL is rejected by gcc for operator new.
// The expedient thing is just not to override operator new.
// While relatively pointless, heap allocated instances will function.
// static void * U_EXPORT2 operator new(size_t size);
// static void * U_EXPORT2 operator new[](size_t size);
#if U_HAVE_PLACEMENT_NEW
// static void * U_EXPORT2 operator new(size_t, void *ptr);
#endif
};
template<typename T, int32_t stackCapacity>
@ -512,6 +505,13 @@ inline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32
template<typename H, typename T, int32_t stackCapacity>
class MaybeStackHeaderAndArray {
public:
// No heap allocation. Use only on the stack.
static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
static void* U_EXPORT2 operator new[](size_t) U_NO_THROW = delete;
#if U_HAVE_PLACEMENT_NEW
static void* U_EXPORT2 operator new(size_t, void*) U_NO_THROW = delete;
#endif
/**
* Default constructor initializes with internal H+T[stackCapacity] buffer.
*/
@ -608,15 +608,6 @@ private:
/* No ownership transfer: No copy constructor, no assignment operator. */
MaybeStackHeaderAndArray(const MaybeStackHeaderAndArray & /*other*/) {}
void operator=(const MaybeStackHeaderAndArray & /*other*/) {}
// No heap allocation. Use only on the stack.
// (Declaring these functions private triggers a cascade of problems;
// see the MaybeStackArray class for details.)
// static void * U_EXPORT2 operator new(size_t size);
// static void * U_EXPORT2 operator new[](size_t size);
#if U_HAVE_PLACEMENT_NEW
// static void * U_EXPORT2 operator new(size_t, void *ptr);
#endif
};
template<typename H, typename T, int32_t stackCapacity>

View file

@ -65,6 +65,13 @@ U_NAMESPACE_BEGIN
template<typename T>
class LocalPointerBase {
public:
// No heap allocation. Use only on the stack.
static void* U_EXPORT2 operator new(size_t) = delete;
static void* U_EXPORT2 operator new[](size_t) = delete;
#if U_HAVE_PLACEMENT_NEW
static void* U_EXPORT2 operator new(size_t, void*) = delete;
#endif
/**
* Constructor takes ownership.
* @param p simple pointer to an object that is adopted
@ -158,12 +165,6 @@ private:
// No ownership sharing: No copy constructor, no assignment operator.
LocalPointerBase(const LocalPointerBase<T> &other);
void operator=(const LocalPointerBase<T> &other);
// No heap allocation. Use only on the stack.
static void * U_EXPORT2 operator new(size_t size);
static void * U_EXPORT2 operator new[](size_t size);
#if U_HAVE_PLACEMENT_NEW
static void * U_EXPORT2 operator new(size_t, void *ptr);
#endif
};
/**

View file

@ -108,6 +108,13 @@ U_NAMESPACE_BEGIN
*/
class StackUResourceBundle {
public:
// No heap allocation. Use only on the stack.
static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
static void* U_EXPORT2 operator new[](size_t) U_NO_THROW = delete;
#if U_HAVE_PLACEMENT_NEW
static void* U_EXPORT2 operator new(size_t, void*) U_NO_THROW = delete;
#endif
StackUResourceBundle();
~StackUResourceBundle();
@ -121,13 +128,6 @@ public:
private:
UResourceBundle bundle;
// No heap allocation. Use only on the stack.
static void* U_EXPORT2 operator new(size_t);
static void* U_EXPORT2 operator new[](size_t);
#if U_HAVE_PLACEMENT_NEW
static void* U_EXPORT2 operator new(size_t, void*);
#endif
};
U_NAMESPACE_END

View file

@ -62,8 +62,11 @@ class FieldPositionIteratorHandler : public FieldPositionHandler {
// to be destroyed before status goes out of scope. Easiest thing is to
// allocate us on the stack in the same (or narrower) scope as status has.
// This attempts to encourage that by blocking heap allocation.
void *operator new(size_t s);
void *operator new[](size_t s);
static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
static void* U_EXPORT2 operator new[](size_t) U_NO_THROW = delete;
#if U_HAVE_PLACEMENT_NEW
static void* U_EXPORT2 operator new(size_t, void*) U_NO_THROW = delete;
#endif
public:
FieldPositionIteratorHandler(FieldPositionIterator* posIter, UErrorCode& status);