diff options
-rw-r--r-- | libcxxabi/include/__cxxabi_config.h | 2 | ||||
-rw-r--r-- | libcxxabi/src/cxa_vector.cpp | 33 |
2 files changed, 31 insertions, 4 deletions
diff --git a/libcxxabi/include/__cxxabi_config.h b/libcxxabi/include/__cxxabi_config.h index fb247308c50..1e0edcab88e 100644 --- a/libcxxabi/include/__cxxabi_config.h +++ b/libcxxabi/include/__cxxabi_config.h @@ -61,6 +61,8 @@ #if defined(__clang__) #define _LIBCXXABI_COMPILER_CLANG +#elif defined(__GNUC__) +#define _LIBCXXABI_COMPILER_GCC #endif #if __has_attribute(__no_sanitize__) && defined(_LIBCXXABI_COMPILER_CLANG) diff --git a/libcxxabi/src/cxa_vector.cpp b/libcxxabi/src/cxa_vector.cpp index f53a956096e..3237b1df523 100644 --- a/libcxxabi/src/cxa_vector.cpp +++ b/libcxxabi/src/cxa_vector.cpp @@ -11,12 +11,17 @@ //===----------------------------------------------------------------------===// #include "cxxabi.h" +#include "__cxxabi_config.h" #include <exception> // for std::terminate #include <new> // for std::bad_alloc #include "abort_message.h" +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + namespace __cxxabiv1 { #if 0 @@ -120,15 +125,35 @@ void throw_bad_array_new_length() { #endif } +bool mul_overflow(size_t x, size_t y, size_t *res) { +#if (defined(_LIBCXXABI_COMPILER_CLANG) && __has_builtin(__builtin_mul_overflow)) \ + || defined(_LIBCXXABI_COMPILER_GCC) + return __builtin_mul_overflow(x, y, res); +#else + *res = x * y; + return x && ((*res / x) != y); +#endif +} + +bool add_overflow(size_t x, size_t y, size_t *res) { +#if (defined(_LIBCXXABI_COMPILER_CLANG) && __has_builtin(__builtin_add_overflow)) \ + || defined(_LIBCXXABI_COMPILER_GCC) + return __builtin_add_overflow(x, y, res); +#else + *res = x + y; + return *res < y; +#endif +} + size_t calculate_allocation_size_or_throw(size_t element_count, size_t element_size, size_t padding_size) { - const size_t element_heap_size = element_count * element_size; - if (element_heap_size / element_count != element_size) + size_t element_heap_size; + if (mul_overflow(element_count, element_size, &element_heap_size)) throw_bad_array_new_length(); - const size_t allocation_size = element_heap_size + padding_size; - if (allocation_size < element_heap_size) + size_t allocation_size; + if (add_overflow(element_heap_size, padding_size, &allocation_size)) throw_bad_array_new_length(); return allocation_size; |