diff options
| author | Edward Thomson <ethomson@microsoft.com> | 2015-02-12 17:36:48 -0500 |
|---|---|---|
| committer | Edward Thomson <ethomson@microsoft.com> | 2015-02-13 09:28:09 -0500 |
| commit | 16942c6fdaddb819b71b72e53aa4aa691e3c0053 (patch) | |
| tree | 05a719c0753521789eff1ebc4c4c284d80afb696 /src/integer.h | |
| parent | 8aab36a3010372edec71e8c765d4ecfd848c09b6 (diff) | |
| download | libgit2-16942c6fdaddb819b71b72e53aa4aa691e3c0053.tar.gz | |
integer overflow: use compiler intrinsics if supported
gcc and clang support __builtin_add_overflow, use it whenever
possible, falling back to our naive routines.
Diffstat (limited to 'src/integer.h')
| -rw-r--r-- | src/integer.h | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/integer.h b/src/integer.h index a4abe2bd1..8e86a48a5 100644 --- a/src/integer.h +++ b/src/integer.h @@ -54,6 +54,19 @@ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t 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. * @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 return false; } +#endif + #endif /* INCLUDE_integer_h__ */ |
