1 #if defined(_HAVE_BUILTIN_MUL_OVERFLOW) && !defined(__MSP430__)
2 // gcc should use the correct one here
3 #define mul_overflow __builtin_mul_overflow
4 #else
5 /**
6  * Since __builtin_mul_overflow doesn't seem to exist,
7  * use a (slower) software implementation instead.
8  * This is only implemented for size_t, so in case mallocr.c's INTERNAL_SIZE_T
9  *  is non default, mallocr.c throws an #error.
10  */
mul_overflow_size_t(size_t a,size_t b,size_t * res)11 static int mul_overflow_size_t(size_t a, size_t b, size_t *res)
12 {
13     // always fill the result (gcc doesn't define what happens here)
14     if (res)
15         *res = a * b;
16 
17     // multiply with 0 can not overflow (and avoid div-by-zero):
18     if (a == 0 || b == 0)
19         return 0;
20 
21 #ifdef __MSP430__
22     volatile uint32_t ia = (uint32_t) a;
23     volatile uint32_t ib = (uint32_t) b;
24 
25     // check if overflow would happen:
26     if ( (ia > SIZE_MAX / ib) || (ib > SIZE_MAX / ia)) {
27         return 1;
28     }
29 #else
30     // check if overflow would happen:
31     if ( (a > SIZE_MAX / b) || (b > SIZE_MAX / a)) {
32         return 1;
33     }
34 #endif
35 
36     return 0;
37 }
38 #define mul_overflow mul_overflow_size_t
39 #endif
40