Commit 2848923a by lhchavez

Let GCC use the add/mul overflow intrinsics

This change tweaks the macros for git__{add,multiply}_sizet_overflow so
that GCC can use them.

It also stops using the uadd,umul versions since the add,mul can handle
way more cases.
parent 19bca3d3
...@@ -55,16 +55,36 @@ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t ...@@ -55,16 +55,36 @@ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t
} }
/* Use clang/gcc compiler intrinsics whenever possible */ /* Use clang/gcc compiler intrinsics whenever possible */
#if (SIZE_MAX == ULONG_MAX) && __has_builtin(__builtin_uaddl_overflow) #if (__has_builtin(__builtin_add_overflow) || \
# define git__add_sizet_overflow(out, one, two) \ (defined(__GNUC__) && (__GNUC__ >= 5)))
__builtin_uaddl_overflow(one, two, out)
# define git__multiply_sizet_overflow(out, one, two) \ /*
__builtin_umull_overflow(one, two, out) * Even though __builtin_{add,mul}_overflow should be able to handle all
#elif (SIZE_MAX == UINT_MAX) && __has_builtin(__builtin_uadd_overflow) * possible cases (since it can accept any type), under some configurations
# define git__add_sizet_overflow(out, one, two) \ * clang would need a dependency on compiler-rt. In order to avoid that, we
__builtin_uadd_overflow(one, two, out) * attempt to choose one of the explicit unsigned long long / unsigned long
# define git__multiply_sizet_overflow(out, one, two) \ * versions of the intrinsics if possible. Unfortunately, unsigned long long
__builtin_umul_overflow(one, two, out) * and unsigned long are still different types to the compiler, so we need to
* still do some additional sniffing to prevent MinGW 64 from choosing the
* wrong version and triggering compiler warnings.
*/
# if (SIZE_MAX == ULLONG_MAX) && (ULONG_MAX == ULLONG_MAX) && defined(_WIN64)
# define git__add_sizet_overflow(out, one, two) \
__builtin_uaddll_overflow(one, two, out)
# define git__multiply_sizet_overflow(out, one, two) \
__builtin_umulll_overflow(one, two, out)
# elif (SIZE_MAX == ULONG_MAX) && (ULONG_MAX == ULLONG_MAX)
# 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
# define git__add_sizet_overflow(out, one, two) \
__builtin_add_overflow(one, two, out)
# define git__multiply_sizet_overflow(out, one, two) \
__builtin_mul_overflow(one, two, out)
# endif
#else #else
/** /**
......
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