[libcxx-commits] [libcxxabi] r358195 - Fix PR41465 - Use __builtin_mul_overflow instead of hand-rolled check.

Eric Fiselier via libcxx-commits libcxx-commits at lists.llvm.org
Thu Apr 11 10:16:35 PDT 2019


Author: ericwf
Date: Thu Apr 11 10:16:35 2019
New Revision: 358195

URL: http://llvm.org/viewvc/llvm-project?rev=358195&view=rev
Log:
Fix PR41465 - Use __builtin_mul_overflow instead of hand-rolled check.

On ARM the hand-rolled check causes a call to __aeabi_uidiv,
which we may not have a definition for.

Using the builtin avoids the generation of any library call.

Modified:
    libcxxabi/trunk/include/__cxxabi_config.h
    libcxxabi/trunk/src/cxa_vector.cpp

Modified: libcxxabi/trunk/include/__cxxabi_config.h
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/include/__cxxabi_config.h?rev=358195&r1=358194&r2=358195&view=diff
==============================================================================
--- libcxxabi/trunk/include/__cxxabi_config.h (original)
+++ libcxxabi/trunk/include/__cxxabi_config.h Thu Apr 11 10:16:35 2019
@@ -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)

Modified: libcxxabi/trunk/src/cxa_vector.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_vector.cpp?rev=358195&r1=358194&r2=358195&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_vector.cpp (original)
+++ libcxxabi/trunk/src/cxa_vector.cpp Thu Apr 11 10:16:35 2019
@@ -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;




More information about the libcxx-commits mailing list