Skip to content

Commit 2848923

Browse files
committed
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.
1 parent 19bca3d commit 2848923

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

src/integer.h

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,36 @@ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t
5555
}
5656

5757
/* Use clang/gcc compiler intrinsics whenever possible */
58-
#if (SIZE_MAX == ULONG_MAX) && __has_builtin(__builtin_uaddl_overflow)
59-
# define git__add_sizet_overflow(out, one, two) \
60-
__builtin_uaddl_overflow(one, two, out)
61-
# define git__multiply_sizet_overflow(out, one, two) \
62-
__builtin_umull_overflow(one, two, out)
63-
#elif (SIZE_MAX == UINT_MAX) && __has_builtin(__builtin_uadd_overflow)
64-
# define git__add_sizet_overflow(out, one, two) \
65-
__builtin_uadd_overflow(one, two, out)
66-
# define git__multiply_sizet_overflow(out, one, two) \
67-
__builtin_umul_overflow(one, two, out)
58+
#if (__has_builtin(__builtin_add_overflow) || \
59+
(defined(__GNUC__) && (__GNUC__ >= 5)))
60+
61+
/*
62+
* Even though __builtin_{add,mul}_overflow should be able to handle all
63+
* possible cases (since it can accept any type), under some configurations
64+
* clang would need a dependency on compiler-rt. In order to avoid that, we
65+
* attempt to choose one of the explicit unsigned long long / unsigned long
66+
* versions of the intrinsics if possible. Unfortunately, unsigned long long
67+
* and unsigned long are still different types to the compiler, so we need to
68+
* still do some additional sniffing to prevent MinGW 64 from choosing the
69+
* wrong version and triggering compiler warnings.
70+
*/
71+
# if (SIZE_MAX == ULLONG_MAX) && (ULONG_MAX == ULLONG_MAX) && defined(_WIN64)
72+
# define git__add_sizet_overflow(out, one, two) \
73+
__builtin_uaddll_overflow(one, two, out)
74+
# define git__multiply_sizet_overflow(out, one, two) \
75+
__builtin_umulll_overflow(one, two, out)
76+
# elif (SIZE_MAX == ULONG_MAX) && (ULONG_MAX == ULLONG_MAX)
77+
# define git__add_sizet_overflow(out, one, two) \
78+
__builtin_uaddl_overflow(one, two, out)
79+
# define git__multiply_sizet_overflow(out, one, two) \
80+
__builtin_umull_overflow(one, two, out)
81+
# else
82+
# define git__add_sizet_overflow(out, one, two) \
83+
__builtin_add_overflow(one, two, out)
84+
# define git__multiply_sizet_overflow(out, one, two) \
85+
__builtin_mul_overflow(one, two, out)
86+
# endif
87+
6888
#else
6989

7090
/**

0 commit comments

Comments
 (0)