3232
3333#include < cstddef>
3434#include < cstdint>
35+ #include < new> // IWYU pragma: keep // `new` operators.
3536
3637#include < godot_cpp/core/defs.hpp>
3738#include < godot_cpp/core/error_macros.hpp>
3839#include < godot_cpp/godot.hpp>
3940
4041#include < type_traits>
4142
42- // p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
43- void *operator new (size_t p_size, const char *p_dummy, const char *p_description); // /< operator new that takes a description and uses MemoryStaticPool
44- void *operator new (size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)); // /< operator new that takes a description and uses MemoryStaticPool
45- void *operator new (size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description); // /< operator new that takes a description and uses a pointer to the preallocated memory
46-
47- _ALWAYS_INLINE_ void *operator new (size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) {
48- return p_pointer;
49- }
50-
51- #ifdef _MSC_VER
52- // When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291).
53- // The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete.
54- void operator delete (void *p_mem, const char *p_dummy, const char *p_description);
55- void operator delete (void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size));
56- void operator delete (void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description);
57- #endif
58-
5943namespace godot {
60-
6144class Wrapped ;
6245
6346namespace Memory {
@@ -92,6 +75,35 @@ void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false);
9275void free_static (void *p_ptr, bool p_pad_align = false );
9376}; // namespace Memory
9477
78+ class DefaultAllocator {
79+ public:
80+ _ALWAYS_INLINE_ static void *alloc (size_t p_memory) { return Memory::alloc_static (p_memory); }
81+ _ALWAYS_INLINE_ static void free (void *p_ptr) { Memory::free_static (p_ptr); }
82+ };
83+
84+ } // namespace godot
85+
86+ // Overload of `new` operator to use the `Memory::alloc_static()` function.
87+ // The `DefaultAllocator` parameter is just a tag to select this overload.
88+ // NOTE: do not inline `new` operators due to GCC+LTO compiler bug (see GH-119752).
89+ void *operator new (size_t p_size, godot::DefaultAllocator p_allocator);
90+
91+ // Overload of `new` operator to use a custom allocation function.
92+ // p_allocator argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
93+ void *operator new (size_t p_size, godot::DefaultAllocator p_allocator, void *(*p_allocfunc)(size_t p_size));
94+
95+ #if defined(_MSC_VER) && !defined(__clang__)
96+ // When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291).
97+ // The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete.
98+ inline void operator delete (void *p_mem, godot::DefaultAllocator p_allocator) {
99+ CRASH_NOW_MSG (" Call to placement delete should not happen." );
100+ }
101+ inline void operator delete (void *p_mem, godot::DefaultAllocator, void *(*p_allocfunc)(size_t p_size)) {
102+ CRASH_NOW_MSG (" Call to placement delete should not happen." );
103+ }
104+ #endif // defined(_MSC_VER) && !defined(__clang__)
105+
106+ namespace godot {
95107template <typename T, std::enable_if_t <!std::is_base_of<::godot::Wrapped, T>::value, bool > = true >
96108_ALWAYS_INLINE_ void _pre_initialize () {}
97109
@@ -117,10 +129,10 @@ _ALWAYS_INLINE_ memnew_result_t<T> _post_initialize(T *p_obj) {
117129#define memrealloc (m_mem, m_size ) ::godot::Memory::realloc_static(m_mem, m_size)
118130#define memfree (m_mem ) ::godot::Memory::free_static(m_mem)
119131
120- #define memnew (m_class ) (::godot::_pre_initialize<std::remove_pointer_t <decltype (new (" " , " " ) m_class)>>(), ::godot::_post_initialize(new (" " , " " ) m_class))
132+ #define memnew (m_class ) (::godot::_pre_initialize<std::remove_pointer_t <decltype (new (godot::DefaultAllocator{} ) m_class)>>(), ::godot::_post_initialize(new (godot::DefaultAllocator{} ) m_class))
121133
122- #define memnew_allocator (m_class, m_allocator ) (::godot::_pre_initialize<std::remove_pointer_t <decltype (new (" " , " " ) m_class)>>(), ::godot::_post_initialize(new (" " , m_allocator::alloc) m_class))
123- #define memnew_placement (m_placement, m_class ) (::godot::_pre_initialize<std::remove_pointer_t <decltype (new (" " , " " ) m_class)>>(), ::godot::_post_initialize(new (" " , m_placement, sizeof (m_class), " " ) m_class))
134+ #define memnew_allocator (m_class, m_allocator ) (::godot::_pre_initialize<std::remove_pointer_t <decltype (new (godot::DefaultAllocator{}, m_allocator::alloc ) m_class)>>(), ::godot::_post_initialize(new (godot::DefaultAllocator{} , m_allocator::alloc) m_class))
135+ #define memnew_placement (m_placement, m_class ) (::godot::_pre_initialize<std::remove_pointer_t <decltype (new (m_placement ) m_class)>>(), ::godot::_post_initialize(new (m_placement) m_class))
124136
125137template <typename T>
126138void memdelete (T *p_class, typename std::enable_if<!std::is_base_of_v<godot::Wrapped, T>>::type * = nullptr ) {
@@ -145,12 +157,6 @@ void memdelete_allocator(T *p_class) {
145157 A::free (p_class);
146158}
147159
148- class DefaultAllocator {
149- public:
150- _ALWAYS_INLINE_ static void *alloc (size_t p_memory) { return Memory::alloc_static (p_memory); }
151- _ALWAYS_INLINE_ static void free (void *p_ptr) { Memory::free_static (p_ptr); }
152- };
153-
154160template <typename T>
155161class DefaultTypedAllocator {
156162public:
@@ -166,7 +172,7 @@ _FORCE_INLINE_ uint64_t *_get_element_count_ptr(uint8_t *p_ptr) {
166172}
167173
168174template <typename T>
169- T *memnew_arr_template (size_t p_elements, const char *p_descr = " " ) {
175+ T *memnew_arr_template (size_t p_elements) {
170176 if (p_elements == 0 ) {
171177 return nullptr ;
172178 }
@@ -186,7 +192,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
186192
187193 /* call operator new */
188194 for (size_t i = 0 ; i < p_elements; i++) {
189- new (" " , &elems[i], sizeof (T), p_descr ) T;
195+ new (&elems[i]) T;
190196 }
191197 }
192198
0 commit comments