|
26 | 26 | #define __typecheck(x, y) \
|
27 | 27 | (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
|
28 | 28 |
|
29 |
| -/* is_signed_type() isn't a constexpr for pointer types */ |
30 |
| -#define __is_signed(x) \ |
31 |
| - __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ |
32 |
| - is_signed_type(typeof(x)), 0) |
| 29 | +/* |
| 30 | + * __sign_use for integer expressions: |
| 31 | + * bit #0 set if ok for unsigned comparisons |
| 32 | + * bit #1 set if ok for signed comparisons |
| 33 | + * |
| 34 | + * In particular, statically non-negative signed integer |
| 35 | + * expressions are ok for both. |
| 36 | + * |
| 37 | + * NOTE! Unsigned types smaller than 'int' are implicitly |
| 38 | + * converted to 'int' in expressions, and are accepted for |
| 39 | + * signed conversions for now. This is debatable. |
| 40 | + * |
| 41 | + * Note that 'x' is the original expression, and 'ux' is |
| 42 | + * the unique variable that contains the value. |
| 43 | + * |
| 44 | + * We use 'ux' for pure type checking, and 'x' for when |
| 45 | + * we need to look at the value (but without evaluating |
| 46 | + * it for side effects! Careful to only ever evaluate it |
| 47 | + * with sizeof() or __builtin_constant_p() etc). |
| 48 | + * |
| 49 | + * Pointers end up being checked by the normal C type |
| 50 | + * rules at the actual comparison, and these expressions |
| 51 | + * only need to be careful to not cause warnings for |
| 52 | + * pointer use. |
| 53 | + */ |
| 54 | +#define __signed_type_use(x,ux) (2+__is_nonneg(x,ux)) |
| 55 | +#define __unsigned_type_use(x,ux) (1+2*(sizeof(ux)<4)) |
| 56 | +#define __sign_use(x,ux) (is_signed_type(typeof(ux))? \ |
| 57 | + __signed_type_use(x,ux):__unsigned_type_use(x,ux)) |
| 58 | + |
| 59 | +/* |
| 60 | + * To avoid warnings about casting pointers to integers |
| 61 | + * of different sizes, we need that special sign type. |
| 62 | + * |
| 63 | + * On 64-bit we can just always use 'long', since any |
| 64 | + * integer or pointer type can just be cast to that. |
| 65 | + * |
| 66 | + * This does not work for 128-bit signed integers since |
| 67 | + * the cast would truncate them, but we do not use s128 |
| 68 | + * types in the kernel (we do use 'u128', but they will |
| 69 | + * be handled by the !is_signed_type() case). |
| 70 | + * |
| 71 | + * NOTE! The cast is there only to avoid any warnings |
| 72 | + * from when values that aren't signed integer types. |
| 73 | + */ |
| 74 | +#ifdef CONFIG_64BIT |
| 75 | + #define __signed_type(ux) long |
| 76 | +#else |
| 77 | + #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux)>4,1LL,1L)) |
| 78 | +#endif |
| 79 | +#define __is_nonneg(x,ux) statically_true((__signed_type(ux))(x)>=0) |
33 | 80 |
|
34 |
| -/* True for a non-negative signed int constant */ |
35 |
| -#define __is_noneg_int(x) \ |
36 |
| - (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0) |
| 81 | +#define __types_ok(x,y,ux,uy) \ |
| 82 | + (__sign_use(x,ux) & __sign_use(y,uy)) |
37 | 83 |
|
38 |
| -#define __types_ok(x, y, ux, uy) \ |
39 |
| - (__is_signed(ux) == __is_signed(uy) || \ |
40 |
| - __is_signed((ux) + 0) == __is_signed((uy) + 0) || \ |
41 |
| - __is_noneg_int(x) || __is_noneg_int(y)) |
| 84 | +#define __types_ok3(x,y,z,ux,uy,uz) \ |
| 85 | + (__sign_use(x,ux) & __sign_use(y,uy) & __sign_use(z,uz)) |
42 | 86 |
|
43 | 87 | #define __cmp_op_min <
|
44 | 88 | #define __cmp_op_max >
|
|
53 | 97 |
|
54 | 98 | #define __careful_cmp_once(op, x, y, ux, uy) ({ \
|
55 | 99 | __auto_type ux = (x); __auto_type uy = (y); \
|
56 |
| - static_assert(__types_ok(x, y, ux, uy), \ |
57 |
| - #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \ |
| 100 | + BUILD_BUG_ON_MSG(!__types_ok(x,y,ux,uy), \ |
| 101 | + #op"("#x", "#y") signedness error"); \ |
58 | 102 | __cmp(op, ux, uy); })
|
59 | 103 |
|
60 | 104 | #define __careful_cmp(op, x, y) \
|
|
70 | 114 | static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \
|
71 | 115 | (lo) <= (hi), true), \
|
72 | 116 | "clamp() low limit " #lo " greater than high limit " #hi); \
|
73 |
| - static_assert(__types_ok(uval, lo, uval, ulo), "clamp() 'lo' signedness error"); \ |
74 |
| - static_assert(__types_ok(uval, hi, uval, uhi), "clamp() 'hi' signedness error"); \ |
| 117 | + BUILD_BUG_ON_MSG(!__types_ok3(val,lo,hi,uval,ulo,uhi), \ |
| 118 | + "clamp("#val", "#lo", "#hi") signedness error"); \ |
75 | 119 | __clamp(uval, ulo, uhi); })
|
76 | 120 |
|
77 | 121 | #define __careful_clamp(val, lo, hi) \
|
|
0 commit comments