diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 59acfb055..898e27b03 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -645,16 +645,17 @@ hb_unsigned_mul_overflows (unsigned int count, unsigned int size) return (size > 0) && (count >= ((unsigned int) -1) / size); } -/* Right now we only have one use for signed overflow and as it - * is GCC 5.1 > and clang we don't care about its fallback ATM */ -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif +static inline bool +hb_int_mul_overflows (int x, int y, int &result) +{ #if __has_builtin(__builtin_mul_overflow) -# define hb_signed_mul_overflows(x, y, result) __builtin_mul_overflow(x, y, &result) + return __builtin_mul_overflow (x, y, &result); #else -# define hb_signed_mul_overflows(x, y, result) (result = (x) * (y), false) + int64_t sink = (int64_t) x * y; + result = sink; + return result != sink; #endif +} /* diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh index f5235ac56..d1f4ecaa2 100644 --- a/src/hb-ot-var-avar-table.hh +++ b/src/hb-ot-var-avar-table.hh @@ -90,9 +90,9 @@ struct SegmentMaps : ArrayOf return arrayZ[i-1].toCoord; int factor; - if (hb_signed_mul_overflows (arrayZ[i].toCoord - arrayZ[i-1].toCoord, - value - arrayZ[i-1].fromCoord, - factor)) + if (unlikely (hb_int_mul_overflows (arrayZ[i].toCoord - arrayZ[i-1].toCoord, + value - arrayZ[i-1].fromCoord, + factor))) return arrayZ[i-1].toCoord; int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord; diff --git a/src/hb.hh b/src/hb.hh index fcbd33058..d4b51cf67 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -219,6 +219,10 @@ extern "C" void hb_free_impl(void *ptr); * Compiler attributes */ +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__) #define likely(expr) (__builtin_expect (!!(expr), 1)) #define unlikely(expr) (__builtin_expect (!!(expr), 0))