Commit 16942c6f by Edward Thomson

integer overflow: use compiler intrinsics if supported

gcc and clang support __builtin_add_overflow, use it whenever
possible, falling back to our naive routines.
parent 8aab36a3
...@@ -17,6 +17,11 @@ ...@@ -17,6 +17,11 @@
# define GIT_INLINE(type) static inline type # define GIT_INLINE(type) static inline type
#endif #endif
/** Support for gcc/clang __has_builtin intrinsic */
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
......
...@@ -54,6 +54,19 @@ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t ...@@ -54,6 +54,19 @@ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t
return false; return false;
} }
/* Use clang/gcc compiler intrinsics whenever possible */
#if (SIZE_MAX == UINT_MAX) && __has_builtin(__builtin_uadd_overflow)
# define git__add_sizet_overflow(out, one, two) \
__builtin_uadd_overflow(one, two, out)
# define git__multiply_sizet_overflow(out, one, two)
__builtin_umul_overflow(one, two, out)
#elif (SIZE_MAX == ULONG_MAX) && __has_builtin(__builtin_uaddl_overflow)
# define git__add_sizet_overflow(out, one, two) \
__builtin_uaddl_overflow(one, two, out)
# define git__multiply_sizet_overflow(out, one, two) \
__builtin_umull_overflow(one, two, out)
#else
/** /**
* Sets `one + two` into `out`, unless the arithmetic would overflow. * Sets `one + two` into `out`, unless the arithmetic would overflow.
* @return true if the result fits in a `size_t`, false on overflow. * @return true if the result fits in a `size_t`, false on overflow.
...@@ -78,4 +91,6 @@ GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out, size_t one, size_t tw ...@@ -78,4 +91,6 @@ GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out, size_t one, size_t tw
return false; return false;
} }
#endif
#endif /* INCLUDE_integer_h__ */ #endif /* INCLUDE_integer_h__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment