diff --git a/libc/src/__support/CPP/new.h b/libc/src/__support/CPP/new.h --- a/libc/src/__support/CPP/new.h +++ b/libc/src/__support/CPP/new.h @@ -9,6 +9,10 @@ #ifndef LLVM_LIBC_SRC_SUPPORT_CPP_NEW_H #define LLVM_LIBC_SRC_SUPPORT_CPP_NEW_H +#ifdef LIBC_COPT_DISABLE_NEW +#warning "new included when LIBC_COPT_DISABLE_NEW is set." +#endif + #include "src/__support/common.h" #include // For size_t @@ -50,6 +54,12 @@ ac = (mem != nullptr); return mem; } + + LIBC_INLINE static void *realloc(void *ptr, size_t s, AllocChecker &ac) { + void *mem = ::realloc(ptr, s); + ac = (mem != nullptr); + return mem; + } }; } // namespace __llvm_libc @@ -74,6 +84,11 @@ return __llvm_libc::AllocChecker::aligned_alloc(size, align, ac); } +LIBC_INLINE void *operator new[](size_t size, void *ptr, + __llvm_libc::AllocChecker &ac) noexcept { + return __llvm_libc::AllocChecker::realloc(ptr, size, ac); +} + // The ideal situation would be to define the various flavors of operator delete // inlinelike we do with operator new above. However, since we need operator // delete prototypes to match those specified by the C++ standard, we cannot diff --git a/libc/src/__support/File/file.cpp b/libc/src/__support/File/file.cpp --- a/libc/src/__support/File/file.cpp +++ b/libc/src/__support/File/file.cpp @@ -355,14 +355,12 @@ if (buffer == nullptr && size != 0 && buffer_mode != _IONBF) { // We exclude the case of buffer_mode == _IONBF in this branch // because we don't need to allocate buffer in such a case. + AllocChecker ac; if (own_buf) { - // This is one of the places where use a C allocation functon - // as C++ does not have an equivalent of realloc. - buf = reinterpret_cast(realloc(buf, size)); - if (buf == nullptr) + buf = reinterpret_cast(AllocChecker::realloc(buf, size, ac)); + if (!ac) return ENOMEM; } else { - AllocChecker ac; buf = new (ac) uint8_t[size]; if (!ac) return ENOMEM; diff --git a/libc/src/__support/char_vector.h b/libc/src/__support/char_vector.h --- a/libc/src/__support/char_vector.h +++ b/libc/src/__support/char_vector.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIBC_SRC_SUPPORT_CHARVECTOR_H #define LLVM_LIBC_SRC_SUPPORT_CHARVECTOR_H +#include "src/__support/CPP/new.h" #include "src/__support/common.h" #include @@ -33,7 +34,7 @@ CharVector() = default; LIBC_INLINE ~CharVector() { if (cur_str != local_buffer) - free(cur_str); + delete (cur_str); } // append returns true on success and false on allocation failure. @@ -42,11 +43,12 @@ if (index >= cur_buff_size - 2) { // If the new character would cause the string to be longer than the // buffer's size, attempt to allocate a new buffer. + AllocChecker ac; cur_buff_size = cur_buff_size * 2; if (cur_str == local_buffer) { char *new_str; - new_str = reinterpret_cast(malloc(cur_buff_size)); - if (new_str == NULL) { + new_str = new (ac) char[cur_buff_size]; + if (!ac) { return false; } // TODO: replace with inline memcpy @@ -54,8 +56,9 @@ new_str[i] = cur_str[i]; cur_str = new_str; } else { - cur_str = reinterpret_cast(realloc(cur_str, cur_buff_size)); - if (cur_str == NULL) { + cur_str = reinterpret_cast( + AllocChecker::realloc(cur_str, cur_buff_size, ac)); + if (!ac) { return false; } }