Backport minmax.h updates from v6.17-rc7
cover Backport minmax.h updates from v6.17-rc7
This series backports 7 patches to update minmax.h in the 6.12.y branch, aligning it with v6.17-rc7.
The ultimate goal is to synchronize all longterm branches so that they include the full set of minmax.h changes.
The key motivation is to bring in commit d03eba99f5bf ("minmax: allow min()/max()/clamp() if the arguments have the same signedness"), which is missing in older kernels.
In mainline, this change enables min()/max()/clamp() to accept mixed argument types, provided both have the same signedness. Without it, backported patches that use these forms may trigger compiler warnings, which escalate to build failures when -Werror is enabled.
David Laight (7):
minmax.h: add whitespace around operators and after commas minmax.h: update some comments
minmax.h: reduce the #define expansion of min(), max() and clamp() minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp() minmax.h: move all the clamp() definitions after the min/max() ones minmax.h: simplify the variants of clamp()
minmax.h: remove some #defines that are only expanded once
include/linux/minmax.h | 205 +++++++++++++++++++---------------------- 1 file changed, 95 insertions(+), 110 deletions(-)
Signature · 1 line
2.47.3
PATCH 1/7 minmax.h: add whitespace around operators and after commas
From: David Laight <[email protected]>
[ Upstream commit 71ee9b16251ea4bf7c1fe222517c82bdb3220acc ]
Patch series "minmax.h: Cleanups and minor optimisations".
Some tidyups and minor changes to minmax.h.
This patch (of 7):
--- include/linux/minmax.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
include/linux/minmax.h +17 -17
@@ -51,10 +51,10 @@* only need to be careful to not cause warnings for * pointer use. */ -#define __signed_type_use (x,ux) (2+__is_nonneg(x,ux)) -#define __unsigned_type_use (x,ux) (1+2*(sizeof(ux)<4)) -#define __sign_use (x,ux) (is_signed_type(typeof(ux))? \ - __signed_type_use(x,ux):__unsigned_type_use(x,ux)) +#define __signed_type_use (x, ux) (2 + __is_nonneg(x, ux)) +#define __unsigned_type_use (x, ux) (1 + 2 * (sizeof(ux) < 4)) +#define __sign_use (x, ux) (is_signed_type(typeof(ux)) ? \ + __signed_type_use(x, ux) : __unsigned_type_use(x, ux))/* * To avoid warnings about casting pointers to integers
@@ -74,15 +74,15 @@#ifdef CONFIG_64BIT #define __signed_type (ux) long#else -#define __signed_type (ux) typeof(__builtin_choose_expr(sizeof(ux)>4,1LL,1L)) +#define __signed_type (ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L))#endif -#define __is_nonneg (x,ux) statically_true((__signed_type(ux))(x)>=0) +#define __is_nonneg (x, ux) statically_true((__signed_type(ux))(x) >= 0) -#define __types_ok (x,y,ux,uy) \ - (__sign_use(x,ux) & __sign_use(y,uy)) +#define __types_ok (x, y, ux, uy) \ + (__sign_use(x, ux) & __sign_use(y, uy)) -#define __types_ok3 (x,y,z,ux,uy,uz) \ - (__sign_use(x,ux) & __sign_use(y,uy) & __sign_use(z,uz)) +#define __types_ok3 (x, y, z, ux, uy, uz) \ + (__sign_use(x, ux) & __sign_use(y, uy) & __sign_use(z, uz))#define __cmp_op_min <#define __cmp_op_max >
@@ -97,7 +97,7 @@#define __careful_cmp_once (op, x, y, ux, uy) ({ \ __auto_type ux = (x); __auto_type uy = (y); \ - BUILD_BUG_ON_MSG(!__types_ok(x,y,ux,uy), \ + BUILD_BUG_ON_MSG(!__types_ok(x, y, ux, uy), \ #op"("#x", "#y") signedness error"); \ __cmp(op, ux, uy); })
@@ -114,7 +114,7 @@ static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ (lo) <= (hi), true), \ "clamp() low limit " #lo " greater than high limit " #hi); \ - BUILD_BUG_ON_MSG(!__types_ok3(val,lo,hi,uval,ulo,uhi), \ + BUILD_BUG_ON_MSG(!__types_ok3(val, lo, hi, uval, ulo, uhi), \ "clamp("#val", "#lo", "#hi") signedness error"); \ __clamp(uval, ulo, uhi); })
@@ -154,7 +154,7 @@#define __careful_op3 (op, x, y, z, ux, uy, uz) ({ \ __auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\ - BUILD_BUG_ON_MSG(!__types_ok3(x,y,z,ux,uy,uz), \ + BUILD_BUG_ON_MSG(!__types_ok3(x, y, z, ux, uy, uz), \ #op"3("#x", "#y", "#z") signedness error"); \ __cmp(op, ux, __cmp(op, uy, uz)); })
@@ -326,9 +326,9 @@ static inline bool in_range32(u32 val, u32 start, u32 len)* Use these carefully: no type checking, and uses the arguments * multiple times. Use for obvious constants only. */ -#define MIN (a,b) __cmp(min,a,b) -#define MAX (a,b) __cmp(max,a,b) -#define MIN_T (type,a,b) __cmp(min,(type)(a),(type)(b)) -#define MAX_T (type,a,b) __cmp(max,(type)(a),(type)(b)) +#define MIN (a, b) __cmp(min, a, b) +#define MAX (a, b) __cmp(max, a, b) +#define MIN_T (type, a, b) __cmp(min, (type)(a), (type)(b)) +#define MAX_T (type, a, b) __cmp(max, (type)(a), (type)(b))#endif /* _LINUX_MINMAX_H */
Signature · 1 line
2.47.3
PATCH 2/7 minmax.h: update some comments
In reply to Eliav FarberFrom: David Laight <[email protected]>
[ Upstream commit 10666e99204818ef45c702469488353b5bb09ec7 ]
- Change three to several.
- Remove the comment about retaining constant expressions, no longer true.
- Realign to nearer 80 columns and break on major punctiation.
- Add a leading comment to the block before __signed_type() and __is_nonneg() Otherwise the block explaining the cast is a bit 'floating'. Reword the rest of that comment to improve readability.
--- include/linux/minmax.h | 53 +++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 29 deletions(-)
include/linux/minmax.h +24 -29
@@ -8,13 +8,10 @@#include <linux/types.h> /* -* min()/max()/clamp() macros must accomplish three things: +* min()/max()/clamp() macros must accomplish several things: * * - Avoid multiple evaluations of the arguments (so side-effects like * "x++" happen only once) when non-constant. -* - Retain result as a constant expressions when called with only -* constant expressions (to avoid tripping VLA warnings in stack -* allocation usage). * - Perform signed v unsigned type-checking (to generate compile * errors instead of nasty runtime surprises). * - Unsigned char/short are always promoted to signed int and can be
@@ -31,25 +28,23 @@* bit #0 set if ok for unsigned comparisons * bit #1 set if ok for signed comparisons * -* In particular, statically non-negative signed integer -* expressions are ok for both. +* In particular, statically non-negative signed integer expressions +* are ok for both. * -* NOTE! Unsigned types smaller than 'int' are implicitly -* converted to 'int' in expressions, and are accepted for -* signed conversions for now. This is debatable. +* NOTE! Unsigned types smaller than 'int' are implicitly converted to 'int' +* in expressions, and are accepted for signed conversions for now. +* This is debatable. * -* Note that 'x' is the original expression, and 'ux' is -* the unique variable that contains the value. +* Note that 'x' is the original expression, and 'ux' is the unique variable +* that contains the value. * -* We use 'ux' for pure type checking, and 'x' for when -* we need to look at the value (but without evaluating -* it for side effects! Careful to only ever evaluate it -* with sizeof() or __builtin_constant_p() etc). +* We use 'ux' for pure type checking, and 'x' for when we need to look at the +* value (but without evaluating it for side effects! +* Careful to only ever evaluate it with sizeof() or __builtin_constant_p() etc). * -* Pointers end up being checked by the normal C type -* rules at the actual comparison, and these expressions -* only need to be careful to not cause warnings for -* pointer use. +* Pointers end up being checked by the normal C type rules at the actual +* comparison, and these expressions only need to be careful to not cause +* warnings for pointer use. */ #define __signed_type_use (x, ux) (2 + __is_nonneg(x, ux))#define __unsigned_type_use (x, ux) (1 + 2 * (sizeof(ux) < 4))
@@ -57,19 +52,19 @@ __signed_type_use(x, ux) : __unsigned_type_use(x, ux))/* -* To avoid warnings about casting pointers to integers -* of different sizes, we need that special sign type. +* Check whether a signed value is always non-negative. * -* On 64-bit we can just always use 'long', since any -* integer or pointer type can just be cast to that. +* A cast is needed to avoid any warnings from values that aren't signed +* integer types (in which case the result doesn't matter). * -* This does not work for 128-bit signed integers since -* the cast would truncate them, but we do not use s128 -* types in the kernel (we do use 'u128', but they will -* be handled by the !is_signed_type() case). +* On 64-bit any integer or pointer type can safely be cast to 'long'. +* But on 32-bit we need to avoid warnings about casting pointers to integers +* of different sizes without truncating 64-bit values so 'long' or 'long long' +* must be used depending on the size of the value. * -* NOTE! The cast is there only to avoid any warnings -* from when values that aren't signed integer types. +* This does not work for 128-bit signed integers since the cast would truncate +* them, but we do not use s128 types in the kernel (we do use 'u128', +* but they are handled by the !is_signed_type() case). */ #ifdef CONFIG_64BIT #define __signed_type (ux) long
Signature · 1 line
2.47.3
PATCH 3/7 minmax.h: reduce the #define expansion of min(), max() and clamp()
In reply to Eliav FarberFrom: David Laight <[email protected]>
[ Upstream commit b280bb27a9f7c91ddab730e1ad91a9c18a051f41 ]
Since the test for signed values being non-negative only relies on __builtion_constant_p() (not is_constexpr()) it can use the 'ux' variable instead of the caller supplied expression. This means that the #define parameters are only expanded twice. Once in the code and once quoted in the error message.
--- include/linux/minmax.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
include/linux/minmax.h +12 -12
@@ -46,10 +46,10 @@* comparison, and these expressions only need to be careful to not cause * warnings for pointer use. */ -#define __signed_type_use (x, ux) (2 + __is_nonneg(x, ux)) -#define __unsigned_type_use (x, ux) (1 + 2 * (sizeof(ux) < 4)) -#define __sign_use (x, ux) (is_signed_type(typeof(ux)) ? \ - __signed_type_use(x, ux) : __unsigned_type_use(x, ux)) +#define __signed_type_use (ux) (2 + __is_nonneg(ux)) +#define __unsigned_type_use (ux) (1 + 2 * (sizeof(ux) < 4)) +#define __sign_use (ux) (is_signed_type(typeof(ux)) ? \ + __signed_type_use(ux) : __unsigned_type_use(ux))/* * Check whether a signed value is always non-negative.
@@ -71,13 +71,13 @@#else #define __signed_type (ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L))#endif -#define __is_nonneg (x, ux) statically_true((__signed_type(ux))(x) >= 0) +#define __is_nonneg (ux) statically_true((__signed_type(ux))(ux) >= 0) -#define __types_ok (x, y, ux, uy) \ - (__sign_use(x, ux) & __sign_use(y, uy)) +#define __types_ok (ux, uy) \ + (__sign_use(ux) & __sign_use(uy)) -#define __types_ok3 (x, y, z, ux, uy, uz) \ - (__sign_use(x, ux) & __sign_use(y, uy) & __sign_use(z, uz)) +#define __types_ok3 (ux, uy, uz) \ + (__sign_use(ux) & __sign_use(uy) & __sign_use(uz))#define __cmp_op_min <#define __cmp_op_max >
@@ -92,7 +92,7 @@#define __careful_cmp_once (op, x, y, ux, uy) ({ \ __auto_type ux = (x); __auto_type uy = (y); \ - BUILD_BUG_ON_MSG(!__types_ok(x, y, ux, uy), \ + BUILD_BUG_ON_MSG(!__types_ok(ux, uy), \ #op"("#x", "#y") signedness error"); \ __cmp(op, ux, uy); })
@@ -109,7 +109,7 @@ static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ (lo) <= (hi), true), \ "clamp() low limit " #lo " greater than high limit " #hi); \ - BUILD_BUG_ON_MSG(!__types_ok3(val, lo, hi, uval, ulo, uhi), \ + BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ "clamp("#val", "#lo", "#hi") signedness error"); \ __clamp(uval, ulo, uhi); })
@@ -149,7 +149,7 @@#define __careful_op3 (op, x, y, z, ux, uy, uz) ({ \ __auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\ - BUILD_BUG_ON_MSG(!__types_ok3(x, y, z, ux, uy, uz), \ + BUILD_BUG_ON_MSG(!__types_ok3(ux, uy, uz), \ #op"3("#x", "#y", "#z") signedness error"); \ __cmp(op, ux, __cmp(op, uy, uz)); })
Signature · 1 line
2.47.3
PATCH 4/7 minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
In reply to Eliav FarberFrom: David Laight <[email protected]>
[ Upstream commit a5743f32baec4728711bbc01d6ac2b33d4c67040 ]
Use BUILD_BUG_ON_MSG(statically_true(ulo > uhi), ...) for the sanity check of the bounds in clamp(). Gives better error coverage and one less expansion of the arguments.
--- include/linux/minmax.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/linux/minmax.h +1 -2
@@ -106,8 +106,7 @@__auto_type uval = (val); \__auto_type ulo = (lo); \__auto_type uhi = (hi); \ - static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ - (lo) <= (hi), true), \ + BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ "clamp() low limit " #lo " greater than high limit " #hi); \ BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ "clamp("#val", "#lo", "#hi") signedness error"); \
Signature · 1 line
2.47.3
PATCH 5/7 minmax.h: move all the clamp() definitions after the min/max() ones
In reply to Eliav FarberFrom: David Laight <[email protected]>
[ Upstream commit c3939872ee4a6b8bdcd0e813c66823b31e6e26f7 ]
At some point the definitions for clamp() got added in the middle of the ones for min() and max(). Re-order the definitions so they are more sensibly grouped.
--- include/linux/minmax.h | 109 +++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 58 deletions(-)
include/linux/minmax.h +51 -58
@@ -99,22 +99,6 @@#define __careful_cmp (op, x, y) \ __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)) -#define __clamp (val, lo, hi) \ - ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) - -#define __clamp_once (val, lo, hi, uval, ulo, uhi) ({ \ - __auto_type uval = (val); \ - __auto_type ulo = (lo); \ - __auto_type uhi = (hi); \ - BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ - "clamp() low limit " #lo " greater than high limit " #hi); \ - BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ - "clamp("#val", "#lo", "#hi") signedness error"); \ - __clamp(uval, ulo, uhi); }) - -#define __careful_clamp (val, lo, hi) \ - __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) -/** * min - return minimum of two values of the same or compatible types * @x: first value
@@ -170,6 +154,22 @@#define max3 (x, y, z) \ __careful_op3(max, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_)) +/** +* min_t - return minimum of two values, using the specified type +* @type: data type to use +* @x: first value +* @y: second value +*/ +#define min_t (type, x, y) __cmp_once(min, type, x, y) + +/** +* max_t - return maximum of two values, using the specified type +* @type: data type to use +* @x: first value +* @y: second value +*/ +#define max_t (type, x, y) __cmp_once(max, type, x, y) +/** * min_not_zero - return the minimum that is _not_ zero, unless both are zero * @x: value1
@@ -180,6 +180,22 @@typeof (y) __y = (y); \ __x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); }) +#define __clamp (val, lo, hi) \ + ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) + +#define __clamp_once (val, lo, hi, uval, ulo, uhi) ({ \ + __auto_type uval = (val); \ + __auto_type ulo = (lo); \ + __auto_type uhi = (hi); \ + BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ + "clamp() low limit " #lo " greater than high limit " #hi); \ + BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ + "clamp("#val", "#lo", "#hi") signedness error"); \ + __clamp(uval, ulo, uhi); }) + +#define __careful_clamp (val, lo, hi) \ + __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) +/** * clamp - return a value clamped to a given range with strict typechecking * @val: current value
@@ -191,28 +207,30 @@*/ #define clamp (val, lo, hi) __careful_clamp(val, lo, hi) -/* -* ..and if you can't take the strict -* types, you can specify one yourself. -* -* Or not use min/max/clamp at all, of course. -*/ -/** -* min_t - return minimum of two values, using the specified type -* @type: data type to use -* @x: first value -* @y: second value +* clamp_t - return a value clamped to a given range using a given type +* @type: the type of variable to use +* @val: current value +* @lo: minimum allowable value +* @hi: maximum allowable value +* +* This macro does no typechecking and uses temporary variables of type +* @type to make all the comparisons. */ -#define min_t (type, x, y) __cmp_once(min, type, x, y) +#define clamp_t (type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi))/** -* max_t - return maximum of two values, using the specified type -* @type: data type to use -* @x: first value -* @y: second value +* clamp_val - return a value clamped to a given range using val's type +* @val: current value +* @lo: minimum allowable value +* @hi: maximum allowable value +* +* This macro does no typechecking and uses temporary variables of whatever +* type the input argument @val is. This is useful when @val is an unsigned +* type and @lo and @hi are literals that will otherwise be assigned a signed +* integer type. */ -#define max_t (type, x, y) __cmp_once(max, type, x, y) +#define clamp_val (val, lo, hi) clamp_t(typeof(val), val, lo, hi)/* * Do not check the array parameter using __must_be_array().
@@ -257,31 +275,6 @@*/ #define max_array (array, len) __minmax_array(max, array, len) -/** -* clamp_t - return a value clamped to a given range using a given type -* @type: the type of variable to use -* @val: current value -* @lo: minimum allowable value -* @hi: maximum allowable value -* -* This macro does no typechecking and uses temporary variables of type -* @type to make all the comparisons. -*/ -#define clamp_t (type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi)) - -/** -* clamp_val - return a value clamped to a given range using val's type -* @val: current value -* @lo: minimum allowable value -* @hi: maximum allowable value -* -* This macro does no typechecking and uses temporary variables of whatever -* type the input argument @val is. This is useful when @val is an unsigned -* type and @lo and @hi are literals that will otherwise be assigned a signed -* integer type. -*/ -#define clamp_val (val, lo, hi) clamp_t(typeof(val), val, lo, hi) -static inline bool in_range64 (u64 val,u64 start,u64 len) {return (val - start) < len;
Signature · 1 line
2.47.3
Greg KH
maintainerRe: [PATCH 5/7 6.12.y] minmax.h: move all the clamp() definitions after the min/max() ones
Quoted 22 lines · Eliav Farber
From: David Laight <[email protected]>
[ Upstream commit
c3939872ee4a6b8bdcd0e813c66823b31e6e26f7]At some point the definitions for
clamp()got added in the middle of the ones formin()andmax(). Re-order the definitions so they are more sensibly grouped.Signed-off-by David Laight <[email protected]>Cc Andy Shevchenko <[email protected]>Cc Arnd Bergmann <[email protected]>Cc Christoph Hellwig <[email protected]>Cc Dan Carpenter <[email protected]>Cc Jason A. Donenfeld <[email protected]>Cc Jens Axboe <[email protected]>Cc Lorenzo Stoakes <[email protected]>Cc Mateusz Guzik <[email protected]>Cc Matthew Wilcox <[email protected]>Cc Pedro Falcato <[email protected]>Signed-off-by Andrew Morton <[email protected]>Signed-off-by Eliav Farber <[email protected]>
Quoted 3 lines
--- include/linux/minmax.h | 109 +++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 58 deletions(-)
This diff looks odd. The upstream commit diffstat is:
include/linux/minmax.h | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------
1 file changed, 62 insertions(+), 69 deletions(-)
which does not match this diffstat, nor the diff itself.
But, if I backport the original commit myself, it matches up exactly with what you show here, which is odd.
diff is "fun", ugh...
Anyway, not a complaint, just something that others might note if they are comparing diffs here like I do.
thanks,
greg k-h
PATCH 6/7 minmax.h: simplify the variants of clamp()
In reply to Eliav FarberFrom: David Laight <[email protected]>
[ Upstream commit 495bba17cdf95e9703af1b8ef773c55ef0dfe703 ]
Always pass a 'type' through to __clamp_once(), pass '__auto_type' from clamp() itself.
The expansion of __types_ok3() is reasonable so it isn't worth the added complexity of avoiding it when a fixed type is used for all three values.
--- include/linux/minmax.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
include/linux/minmax.h +12 -12
@@ -183,29 +183,29 @@#define __clamp (val, lo, hi) \ ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) -#define __clamp_once (val, lo, hi, uval, ulo, uhi) ({ \ - __auto_type uval = (val); \ - __auto_type ulo = (lo); \ - __auto_type uhi = (hi); \ +#define __clamp_once (type, val, lo, hi, uval, ulo, uhi) ({ \ + type uval = (val); \ + type ulo = (lo); \ + type uhi = (hi); \ BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ "clamp() low limit " #lo " greater than high limit " #hi); \ BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ "clamp("#val", "#lo", "#hi") signedness error"); \ __clamp(uval, ulo, uhi); }) -#define __careful_clamp (val, lo, hi) \ - __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) +#define __careful_clamp (type, val, lo, hi) \ + __clamp_once(type, val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_))/** -* clamp - return a value clamped to a given range with strict typechecking +* clamp - return a value clamped to a given range with typechecking * @val: current value * @lo: lowest allowable value * @hi: highest allowable value * -* This macro does strict typechecking of @lo/@hi to make sure they are of the -* same type as @val. See the unnecessary pointer comparisons. +* This macro checks @val/@lo/@hi to make sure they have compatible +* signedness. */ -#define clamp (val, lo, hi) __careful_clamp(val, lo, hi) +#define clamp (val, lo, hi) __careful_clamp(__auto_type, val, lo, hi)/** * clamp_t - return a value clamped to a given range using a given type
@@ -217,7 +217,7 @@* This macro does no typechecking and uses temporary variables of type * @type to make all the comparisons. */ -#define clamp_t (type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi)) +#define clamp_t (type, val, lo, hi) __careful_clamp(type, val, lo, hi)/** * clamp_val - return a value clamped to a given range using val's type
@@ -230,7 +230,7 @@* type and @lo and @hi are literals that will otherwise be assigned a signed * integer type. */ -#define clamp_val (val, lo, hi) clamp_t(typeof(val), val, lo, hi) +#define clamp_val (val, lo, hi) __careful_clamp(typeof(val), val, lo, hi)/* * Do not check the array parameter using __must_be_array().
Signature · 1 line
2.47.3
PATCH 7/7 minmax.h: remove some #defines that are only expanded once
In reply to Eliav FarberFrom: David Laight <[email protected]>
[ Upstream commit 2b97aaf74ed534fb838d09867d09a3ca5d795208 ]
The bodies of __signed_type_use() and __unsigned_type_use() are much the same size as their names - so put the bodies in the only line that expands them.
Similarly __signed_type() is defined separately for 64bit and then used exactly once just below.
Change the test for __signed_type from CONFIG_64BIT to one based on gcc defined macros so that the code is valid if it gets used outside of a kernel build.
--- include/linux/minmax.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
include/linux/minmax.h +6 -8
@@ -46,10 +46,8 @@* comparison, and these expressions only need to be careful to not cause * warnings for pointer use. */ -#define __signed_type_use (ux) (2 + __is_nonneg(ux)) -#define __unsigned_type_use (ux) (1 + 2 * (sizeof(ux) < 4))#define __sign_use (ux) (is_signed_type(typeof(ux)) ? \ - __signed_type_use(ux) : __unsigned_type_use(ux)) + (2 + __is_nonneg(ux)) : (1 + 2 * (sizeof(ux) < 4)))/* * Check whether a signed value is always non-negative.
@@ -57,7 +55,7 @@* A cast is needed to avoid any warnings from values that aren't signed * integer types (in which case the result doesn't matter). * -* On 64-bit any integer or pointer type can safely be cast to 'long'. +* On 64-bit any integer or pointer type can safely be cast to 'long long'. * But on 32-bit we need to avoid warnings about casting pointers to integers * of different sizes without truncating 64-bit values so 'long' or 'long long' * must be used depending on the size of the value.
@@ -66,12 +64,12 @@* them, but we do not use s128 types in the kernel (we do use 'u128', * but they are handled by the !is_signed_type() case). */ -#ifdef CONFIG_64BIT -#define __signed_type (ux) long +#if __SIZEOF_POINTER__ == __SIZEOF_LONG_LONG__ +#define __is_nonneg (ux) statically_true((long long)(ux) >= 0)#else -#define __signed_type (ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)) +#define __is_nonneg (ux) statically_true( \ + (typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)))(ux) >= 0)#endif -#define __is_nonneg (ux) statically_true((__signed_type(ux))(ux) >= 0)#define __types_ok (ux, uy) \ (__sign_use(ux) & __sign_use(uy))
Signature · 1 line
2.47.3
Greg KH
maintainerQuoted 6 lines · Eliav Farber
This series backports 7 patches to update
minmax.hin the 6.12.y branch, aligning it with v6.17-rc7.The ultimate goal is to synchronize all longterm branches so that they include the full set of
minmax.hchanges.
Quoted 8 lines
The key motivation is to bring in commit
d03eba99f5bf("minmax: allow min()/max()/clamp() if the arguments have the same signedness"), which is missing in older kernels.In mainline, this change enables min()/max()/clamp() to accept mixed argument types, provided both have the same signedness. Without it, backported patches that use these forms may trigger compiler warnings, which escalate to build failures when -Werror is enabled.
All now queued up, thanks!
greg k-h