Skip to content

Commit 21b136c

Browse files
committed
minmax: fix up min3() and max3() too
David Laight pointed out that we should deal with the min3() and max3() mess too, which still does excessive expansion. And our current macros are actually rather broken. In particular, the macros did this: #define min3(x, y, z) min((typeof(x))min(x, y), z) #define max3(x, y, z) max((typeof(x))max(x, y), z) and that not only is a nested expansion of possibly very complex arguments with all that involves, the typing with that "typeof()" cast is completely wrong. For example, imagine what happens in max3() if 'x' happens to be a 'unsigned char', but 'y' and 'z' are 'unsigned long'. The types are compatible, and there's no warning - but the result is just random garbage. No, I don't think we've ever hit that issue in practice, but since we now have sane infrastructure for doing this right, let's just use it. It fixes any excessive expansion, and also avoids these kinds of broken type issues. Requested-by: David Laight <[email protected]> Acked-by: Arnd Bergmann <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent e4fc196 commit 21b136c

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

include/linux/minmax.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,21 +152,29 @@
152152
#define umax(x, y) \
153153
__careful_cmp(max, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull)
154154

155+
#define __careful_op3(op, x, y, z, ux, uy, uz) ({ \
156+
__auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\
157+
BUILD_BUG_ON_MSG(!__types_ok3(x,y,z,ux,uy,uz), \
158+
#op"3("#x", "#y", "#z") signedness error"); \
159+
__cmp(op, ux, __cmp(op, uy, uz)); })
160+
155161
/**
156162
* min3 - return minimum of three values
157163
* @x: first value
158164
* @y: second value
159165
* @z: third value
160166
*/
161-
#define min3(x, y, z) min((typeof(x))min(x, y), z)
167+
#define min3(x, y, z) \
168+
__careful_op3(min, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_))
162169

163170
/**
164171
* max3 - return maximum of three values
165172
* @x: first value
166173
* @y: second value
167174
* @z: third value
168175
*/
169-
#define max3(x, y, z) max((typeof(x))max(x, y), z)
176+
#define max3(x, y, z) \
177+
__careful_op3(max, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_))
170178

171179
/**
172180
* min_not_zero - return the minimum that is _not_ zero, unless both are zero

0 commit comments

Comments
 (0)