include/linux/minmax.h | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/include/linux/minmax.h b/include/linux/minmax.h index e3e4353df983..7ad992d5e464 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -26,19 +26,23 @@ #define __typecheck(x, y) \ (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) -/* is_signed_type() isn't a constexpr for pointer types */ -#define __is_signed(x) \ - __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ - is_signed_type(typeof(x)), 0) +/* + * __sign_use for integer expressions: + * bit 1 set if ok for signed comparisons, + * bit 2 set if ok for unsigned comparisons + * + * In particular, non-negative integer constants + * are ok for both. + */ +#define __sign_use(x,ux) \ + (is_signed_type(typeof(ux))?1+2*__is_nonneg(x,ux):2) /* True for a non-negative signed int constant */ -#define __is_noneg_int(x) \ - (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0) +#define __is_nonneg(x,ux) \ + (__builtin_constant_p(x) && !((long long)(x)>>63)) -#define __types_ok(x, y, ux, uy) \ - (__is_signed(ux) == __is_signed(uy) || \ - __is_signed((ux) + 0) == __is_signed((uy) + 0) || \ - __is_noneg_int(x) || __is_noneg_int(y)) +#define __types_ok(x, y, ux, uy) \ + (!!(__sign_use(x,ux) & __sign_use(y,uy))) #define __cmp_op_min < #define __cmp_op_max > @@ -53,8 +57,8 @@ #define __careful_cmp_once(op, x, y, ux, uy) ({ \ __auto_type ux = (x); __auto_type uy = (y); \ - static_assert(__types_ok(x, y, ux, uy), \ - #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \ + BUILD_BUG_ON_MSG(!__types_ok(x, y, ux, uy), \ + #op"("#x", "#y") signedness error"); \ __cmp(op, ux, uy); }) #define __careful_cmp(op, x, y) \ @@ -70,8 +74,10 @@ static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ (lo) <= (hi), true), \ "clamp() low limit " #lo " greater than high limit " #hi); \ - static_assert(__types_ok(uval, lo, uval, ulo), "clamp() 'lo' signedness error"); \ - static_assert(__types_ok(uval, hi, uval, uhi), "clamp() 'hi' signedness error"); \ + BUILD_BUG_ON_MSG(!__types_ok(uval, lo, uval, ulo), \ + "clamp("#val", "#lo", ...) signedness error"); \ + BUILD_BUG_ON_MSG(!__types_ok(uval, hi, uval, uhi), \ + "clamp("#val", ..., "#hi") signedness error"); \ __clamp(uval, ulo, uhi); }) #define __careful_clamp(val, lo, hi) \