diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2018-05-14 17:17:30 +0200 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2018-05-15 17:15:23 +0200 |
commit | ecdedc94e72049d79afda94488b8d67974eb7583 (patch) | |
tree | 925364539b334dc2f81e5a32c4d770dc95b117b3 /lib | |
parent | 9a8117de1263a61702d2b1cd81a9339fd77624cb (diff) |
util: update fallback SUB_OVERFLOW() macro
Updates the fallback SUB_OVERFLOW() macro to better support mixed types
in the arguments.
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libutils/ext/include/compiler.h | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/lib/libutils/ext/include/compiler.h b/lib/libutils/ext/include/compiler.h index eb1842fe..d86be9d7 100644 --- a/lib/libutils/ext/include/compiler.h +++ b/lib/libutils/ext/include/compiler.h @@ -150,23 +150,35 @@ #define __INTOF_SUB(c, a, b) (__extension__({ \ typeof(a) __intofs_a = a; \ typeof(b) __intofs_b = b; \ - int __infos_b_signed = !!__INTOF_MIN(typeof(b)); \ - int __infos_c_signed = !!__INTOF_MIN(typeof(c)); \ + intmax_t __intofs_a_signed = __intofs_a; \ + uintmax_t __intofs_a_unsigned = __intofs_a; \ + intmax_t __intofs_b_signed = __intofs_b; \ + uintmax_t __intofs_b_unsigned = __intofs_b; \ \ __intofs_b < 1 ? \ - ((__INTOF_MAX(typeof(c)) + __intofs_b >= __intofs_a) ? \ - __INTOF_ASSIGN((c), __intofs_a - __intofs_b) : 1) : \ - /* \ - * First deal with special case where c is signed and b is \ - * unsigned, and __INTOF_MIN(typeof(c)) + __intofs_b would \ - * have been a negative number if the expression wasn't \ - * promoted to an unsigned type. \ - */ \ - (((__infos_c_signed && !__infos_b_signed && \ - ((uintmax_t)__INTOF_MAX_SIGNED(typeof(c)) >= \ - (uintmax_t)__intofs_b)) || \ - (__INTOF_MIN(typeof(c)) + __intofs_b <= __intofs_a)) ? \ - __INTOF_ASSIGN((c), __intofs_a - __intofs_b) : 1); \ + __intofs_a < 1 ? \ + ((INTMAX_MAX + __intofs_b >= __intofs_a) ? \ + __INTOF_ASSIGN((c), __intofs_a_signed - \ + __intofs_b_signed) : 1) \ + : \ + (((uintmax_t)(UINTMAX_MAX + __intofs_b_signed) >= \ + __intofs_a_unsigned) ? \ + __INTOF_ASSIGN((c), __intofs_a - \ + __intofs_b) : 1) \ + : \ + __intofs_a < 1 ? \ + (((INTMAX_MIN + __intofs_b <= __intofs_a)) ? \ + __INTOF_ASSIGN((c), \ + (intmax_t)(__intofs_a_signed - \ + __intofs_b_unsigned)) : 1) \ + : \ + ((__intofs_b_unsigned <= __intofs_a_unsigned) ? \ + __INTOF_ASSIGN((c), __intofs_a_unsigned - \ + __intofs_b_unsigned) \ + : \ + __INTOF_ASSIGN((c), \ + (intmax_t)(__intofs_a_unsigned - \ + __intofs_b_unsigned))); \ })) /* |