Skip to content

Commit 86b522b

Browse files
authored
Merge pull request libgit2#4945 from libgit2/ethomson/fix-intrinsics
Add/multiply with overflow tweaks
2 parents b5a3ef3 + 75444d9 commit 86b522b

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

src/integer.h

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,44 @@ GIT_INLINE(int) git__is_int(long long p)
4242
return p == (long long)r;
4343
}
4444

45-
/**
46-
* Sets `one + two` into `out`, unless the arithmetic would overflow.
47-
* @return true if the result fits in a `uint64_t`, false on overflow.
48-
*/
49-
GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t two)
50-
{
51-
if (UINT64_MAX - one < two)
52-
return true;
53-
*out = one + two;
54-
return false;
55-
}
56-
5745
/* 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)
46+
#if (__has_builtin(__builtin_add_overflow) || \
47+
(defined(__GNUC__) && (__GNUC__ >= 5)))
48+
49+
# if (SIZE_MAX == UINT_MAX)
50+
# define git__add_sizet_overflow(out, one, two) \
51+
__builtin_uadd_overflow(one, two, out)
52+
# define git__multiply_sizet_overflow(out, one, two) \
53+
__builtin_umul_overflow(one, two, out)
54+
# elif (SIZE_MAX == ULONG_MAX)
55+
# define git__add_sizet_overflow(out, one, two) \
56+
__builtin_uaddl_overflow(one, two, out)
57+
# define git__multiply_sizet_overflow(out, one, two) \
58+
__builtin_umull_overflow(one, two, out)
59+
# elif (SIZE_MAX == ULLONG_MAX)
60+
# define git__add_sizet_overflow(out, one, two) \
61+
__builtin_uaddll_overflow(one, two, out)
62+
# define git__multiply_sizet_overflow(out, one, two) \
63+
__builtin_umulll_overflow(one, two, out)
64+
# else
65+
# error compiler has add with overflow intrinsics but SIZE_MAX is unknown
66+
# endif
67+
68+
/* Use Microsoft's safe integer handling functions where available */
69+
#elif defined(_MSC_VER)
70+
71+
# include <intsafe.h>
72+
6473
# define git__add_sizet_overflow(out, one, two) \
65-
__builtin_uadd_overflow(one, two, out)
74+
(SizeTAdd(one, two, out) != S_OK)
6675
# define git__multiply_sizet_overflow(out, one, two) \
67-
__builtin_umul_overflow(one, two, out)
76+
(SizeTMult(one, two, out) != S_OK)
77+
6878
#else
6979

7080
/**
7181
* Sets `one + two` into `out`, unless the arithmetic would overflow.
72-
* @return true if the result fits in a `size_t`, false on overflow.
82+
* @return false if the result fits in a `size_t`, true on overflow.
7383
*/
7484
GIT_INLINE(bool) git__add_sizet_overflow(size_t *out, size_t one, size_t two)
7585
{
@@ -81,7 +91,7 @@ GIT_INLINE(bool) git__add_sizet_overflow(size_t *out, size_t one, size_t two)
8191

8292
/**
8393
* Sets `one * two` into `out`, unless the arithmetic would overflow.
84-
* @return true if the result fits in a `size_t`, false on overflow.
94+
* @return false if the result fits in a `size_t`, true on overflow.
8595
*/
8696
GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out, size_t one, size_t two)
8797
{

0 commit comments

Comments
 (0)