Commit 7f8ae01913e408bf219ab41036bd68265596c917

lhchavez 2020-12-18T07:03:21

Avoid using `__builtin_mul_overflow` with the clang+32-bit combo This causes clang to produce an undefined reference to `__mulodi4`. This could be fixed by statically linking some compiler-rt libraries to provide this symbol, but let's first stop the bleeding since doing the correct long-term fix requires some non-trivial CMake knowledge which I lack.

diff --git a/src/integer.h b/src/integer.h
index 026a1fa..28122a9 100644
--- a/src/integer.h
+++ b/src/integer.h
@@ -79,8 +79,12 @@ GIT_INLINE(int) git__is_int(long long p)
 
 # define git__add_int64_overflow(out, one, two) \
     __builtin_add_overflow(one, two, out)
-# define git__multiply_int64_overflow(out, one, two) \
-    __builtin_mul_overflow(one, two, out)
+
+/* clang on 32-bit systems produces an undefined reference to `__mulodi4`. */
+# if !defined(__clang__) || !defined(GIT_ARCH_32)
+#  define git__multiply_int64_overflow(out, one, two) \
+     __builtin_mul_overflow(one, two, out)
+# endif
 
 /* Use Microsoft's safe integer handling functions where available */
 #elif defined(_MSC_VER)
@@ -156,6 +160,10 @@ GIT_INLINE(bool) git__add_int64_overflow(int64_t *out, int64_t one, int64_t two)
 	return false;
 }
 
+#endif
+
+/* If we could not provide an intrinsic implementation for this, provide a (slow) fallback. */
+#if !defined(git__multiply_int64_overflow)
 GIT_INLINE(bool) git__multiply_int64_overflow(int64_t *out, int64_t one, int64_t two)
 {
 	if ((one == -1 && two == INT_MIN) ||
@@ -166,7 +174,6 @@ GIT_INLINE(bool) git__multiply_int64_overflow(int64_t *out, int64_t one, int64_t
 	*out = one * two;
 	return false;
 }
-
 #endif
 
 #endif