File: mul_overflow.h

package info (click to toggle)
picolibc 1.8.11-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 50,064 kB
  • sloc: ansic: 404,031; asm: 24,984; sh: 2,585; python: 2,289; perl: 680; pascal: 329; exp: 287; makefile: 222; cpp: 71; xml: 40
file content (40 lines) | stat: -rw-r--r-- 1,078 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#if __HAVE_BUILTIN_MUL_OVERFLOW && !defined(__MSP430__)
// gcc should use the correct one here
#define mul_overflow __builtin_mul_overflow
#else
/**
 * Since __builtin_mul_overflow doesn't seem to exist,
 * use a (slower) software implementation instead.
 * This is only implemented for size_t, so in case mallocr.c's INTERNAL_SIZE_T
 *  is non default, mallocr.c throws an #error.
 */
static int
mul_overflow_size_t(size_t a, size_t b, size_t *res)
{
    // always fill the result (gcc doesn't define what happens here)
    if (res)
        *res = a * b;

    // multiply with 0 can not overflow (and avoid div-by-zero):
    if (a == 0 || b == 0)
        return 0;

#ifdef __MSP430__
    volatile uint32_t ia = (uint32_t)a;
    volatile uint32_t ib = (uint32_t)b;

    // check if overflow would happen:
    if ((ia > SIZE_MAX / ib) || (ib > SIZE_MAX / ia)) {
        return 1;
    }
#else
    // check if overflow would happen:
    if ((a > SIZE_MAX / b) || (b > SIZE_MAX / a)) {
        return 1;
    }
#endif

    return 0;
}
#define mul_overflow mul_overflow_size_t
#endif