fundamental: Add overflow-safe math helpers
ADD_SAFE/SUB_SAFE/MUL_SAFE do addition/subtraction/multiplication respectively with an overflow check. If an overflow occurs these return false, otherwise true. Example: (c = a + b) would become ADD_SAFE(&c, a, b) INC_SAFE/DEC_SAFE/MUL_ASSIGN_SAFE are like above but they also reassign the first argument. Example: (a += b) would become INC_SAFE(&a, b)
This commit is contained in:
@@ -249,6 +249,30 @@
|
||||
CONST_ISPOWEROF2(_x); \
|
||||
}))
|
||||
|
||||
#define ADD_SAFE(ret, a, b) (!__builtin_add_overflow(a, b, ret))
|
||||
#define INC_SAFE(a, b) __INC_SAFE(UNIQ, a, b)
|
||||
#define __INC_SAFE(q, a, b) \
|
||||
({ \
|
||||
const typeof(a) UNIQ_T(A, q) = (a); \
|
||||
ADD_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \
|
||||
})
|
||||
|
||||
#define SUB_SAFE(ret, a, b) (!__builtin_sub_overflow(a, b, ret))
|
||||
#define DEC_SAFE(a, b) __DEC_SAFE(UNIQ, a, b)
|
||||
#define __DEC_SAFE(q, a, b) \
|
||||
({ \
|
||||
const typeof(a) UNIQ_T(A, q) = (a); \
|
||||
SUB_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \
|
||||
})
|
||||
|
||||
#define MUL_SAFE(ret, a, b) (!__builtin_mul_overflow(a, b, ret))
|
||||
#define MUL_ASSIGN_SAFE(a, b) __MUL_ASSIGN_SAFE(UNIQ, a, b)
|
||||
#define __MUL_ASSIGN_SAFE(q, a, b) \
|
||||
({ \
|
||||
const typeof(a) UNIQ_T(A, q) = (a); \
|
||||
MUL_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \
|
||||
})
|
||||
|
||||
#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
|
||||
#define __LESS_BY(aq, a, bq, b) \
|
||||
({ \
|
||||
@@ -298,7 +322,7 @@
|
||||
const typeof(y) UNIQ_T(A, q) = (y); \
|
||||
const typeof(x) UNIQ_T(B, q) = DIV_ROUND_UP((x), UNIQ_T(A, q)); \
|
||||
typeof(x) UNIQ_T(C, q); \
|
||||
__builtin_mul_overflow(UNIQ_T(B, q), UNIQ_T(A, q), &UNIQ_T(C, q)) ? (typeof(x)) -1 : UNIQ_T(C, q); \
|
||||
MUL_SAFE(&UNIQ_T(C, q), UNIQ_T(B, q), UNIQ_T(A, q)) ? UNIQ_T(C, q) : (typeof(x)) -1; \
|
||||
})
|
||||
#define ROUND_UP(x, y) __ROUND_UP(UNIQ, (x), (y))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user