summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libcxxabi/include/__cxxabi_config.h2
-rw-r--r--libcxxabi/src/cxa_vector.cpp33
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;
OpenPOWER on IntegriCloud