Skip to content

Commit 2d3901a

Browse files
committed
ICU-20271 Use C++11 operator new = delete to disallow heap allocation.
1 parent 6c781b1 commit 2d3901a

File tree

4 files changed

+33
-38
lines changed

4 files changed

+33
-38
lines changed

icu4c/source/common/cmemory.h

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,13 @@ inline T *LocalMemory<T>::allocateInsteadAndCopy(int32_t newCapacity, int32_t le
290290
template<typename T, int32_t stackCapacity>
291291
class MaybeStackArray {
292292
public:
293+
// No heap allocation. Use only on the stack.
294+
static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
295+
static void* U_EXPORT2 operator new[](size_t) U_NO_THROW = delete;
296+
#if U_HAVE_PLACEMENT_NEW
297+
static void* U_EXPORT2 operator new(size_t, void*) U_NO_THROW = delete;
298+
#endif
299+
293300
/**
294301
* Default constructor initializes with internal T[stackCapacity] buffer.
295302
*/
@@ -402,20 +409,6 @@ class MaybeStackArray {
402409
/* No ownership transfer: No copy constructor, no assignment operator. */
403410
MaybeStackArray(const MaybeStackArray & /*other*/) {}
404411
void operator=(const MaybeStackArray & /*other*/) {}
405-
406-
// No heap allocation. Use only on the stack.
407-
// (Declaring these functions private triggers a cascade of problems:
408-
// MSVC insists on exporting an instantiation of MaybeStackArray, which
409-
// requires that all functions be defined.
410-
// An empty implementation of new() is rejected, it must return a value.
411-
// Returning NULL is rejected by gcc for operator new.
412-
// The expedient thing is just not to override operator new.
413-
// While relatively pointless, heap allocated instances will function.
414-
// static void * U_EXPORT2 operator new(size_t size);
415-
// static void * U_EXPORT2 operator new[](size_t size);
416-
#if U_HAVE_PLACEMENT_NEW
417-
// static void * U_EXPORT2 operator new(size_t, void *ptr);
418-
#endif
419412
};
420413

421414
template<typename T, int32_t stackCapacity>
@@ -512,6 +505,13 @@ inline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32
512505
template<typename H, typename T, int32_t stackCapacity>
513506
class MaybeStackHeaderAndArray {
514507
public:
508+
// No heap allocation. Use only on the stack.
509+
static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
510+
static void* U_EXPORT2 operator new[](size_t) U_NO_THROW = delete;
511+
#if U_HAVE_PLACEMENT_NEW
512+
static void* U_EXPORT2 operator new(size_t, void*) U_NO_THROW = delete;
513+
#endif
514+
515515
/**
516516
* Default constructor initializes with internal H+T[stackCapacity] buffer.
517517
*/
@@ -608,15 +608,6 @@ class MaybeStackHeaderAndArray {
608608
/* No ownership transfer: No copy constructor, no assignment operator. */
609609
MaybeStackHeaderAndArray(const MaybeStackHeaderAndArray & /*other*/) {}
610610
void operator=(const MaybeStackHeaderAndArray & /*other*/) {}
611-
612-
// No heap allocation. Use only on the stack.
613-
// (Declaring these functions private triggers a cascade of problems;
614-
// see the MaybeStackArray class for details.)
615-
// static void * U_EXPORT2 operator new(size_t size);
616-
// static void * U_EXPORT2 operator new[](size_t size);
617-
#if U_HAVE_PLACEMENT_NEW
618-
// static void * U_EXPORT2 operator new(size_t, void *ptr);
619-
#endif
620611
};
621612

622613
template<typename H, typename T, int32_t stackCapacity>

icu4c/source/common/unicode/localpointer.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ U_NAMESPACE_BEGIN
6565
template<typename T>
6666
class LocalPointerBase {
6767
public:
68+
// No heap allocation. Use only on the stack.
69+
static void* U_EXPORT2 operator new(size_t) = delete;
70+
static void* U_EXPORT2 operator new[](size_t) = delete;
71+
#if U_HAVE_PLACEMENT_NEW
72+
static void* U_EXPORT2 operator new(size_t, void*) = delete;
73+
#endif
74+
6875
/**
6976
* Constructor takes ownership.
7077
* @param p simple pointer to an object that is adopted
@@ -158,12 +165,6 @@ class LocalPointerBase {
158165
// No ownership sharing: No copy constructor, no assignment operator.
159166
LocalPointerBase(const LocalPointerBase<T> &other);
160167
void operator=(const LocalPointerBase<T> &other);
161-
// No heap allocation. Use only on the stack.
162-
static void * U_EXPORT2 operator new(size_t size);
163-
static void * U_EXPORT2 operator new[](size_t size);
164-
#if U_HAVE_PLACEMENT_NEW
165-
static void * U_EXPORT2 operator new(size_t, void *ptr);
166-
#endif
167168
};
168169

169170
/**

icu4c/source/common/uresimp.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ U_NAMESPACE_BEGIN
108108
*/
109109
class StackUResourceBundle {
110110
public:
111+
// No heap allocation. Use only on the stack.
112+
static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
113+
static void* U_EXPORT2 operator new[](size_t) U_NO_THROW = delete;
114+
#if U_HAVE_PLACEMENT_NEW
115+
static void* U_EXPORT2 operator new(size_t, void*) U_NO_THROW = delete;
116+
#endif
117+
111118
StackUResourceBundle();
112119
~StackUResourceBundle();
113120

@@ -121,13 +128,6 @@ class StackUResourceBundle {
121128

122129
private:
123130
UResourceBundle bundle;
124-
125-
// No heap allocation. Use only on the stack.
126-
static void* U_EXPORT2 operator new(size_t);
127-
static void* U_EXPORT2 operator new[](size_t);
128-
#if U_HAVE_PLACEMENT_NEW
129-
static void* U_EXPORT2 operator new(size_t, void*);
130-
#endif
131131
};
132132

133133
U_NAMESPACE_END

icu4c/source/i18n/fphdlimp.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,11 @@ class FieldPositionIteratorHandler : public FieldPositionHandler {
6262
// to be destroyed before status goes out of scope. Easiest thing is to
6363
// allocate us on the stack in the same (or narrower) scope as status has.
6464
// This attempts to encourage that by blocking heap allocation.
65-
void *operator new(size_t s);
66-
void *operator new[](size_t s);
65+
static void* U_EXPORT2 operator new(size_t) U_NO_THROW = delete;
66+
static void* U_EXPORT2 operator new[](size_t) U_NO_THROW = delete;
67+
#if U_HAVE_PLACEMENT_NEW
68+
static void* U_EXPORT2 operator new(size_t, void*) U_NO_THROW = delete;
69+
#endif
6770

6871
public:
6972
FieldPositionIteratorHandler(FieldPositionIterator* posIter, UErrorCode& status);

0 commit comments

Comments
 (0)