xref: /linux-6.15/include/linux/overflow.h (revision d8e45f29)
1f0907827SRasmus Villemoes /* SPDX-License-Identifier: GPL-2.0 OR MIT */
2f0907827SRasmus Villemoes #ifndef __LINUX_OVERFLOW_H
3f0907827SRasmus Villemoes #define __LINUX_OVERFLOW_H
4f0907827SRasmus Villemoes 
5f0907827SRasmus Villemoes #include <linux/compiler.h>
6a4947e84SLeon Romanovsky #include <linux/limits.h>
7230f6fa2SKees Cook #include <linux/const.h>
8f0907827SRasmus Villemoes 
9f0907827SRasmus Villemoes /*
104eb6bd55SNick Desaulniers  * We need to compute the minimum and maximum values representable in a given
114eb6bd55SNick Desaulniers  * type. These macros may also be useful elsewhere. It would seem more obvious
124eb6bd55SNick Desaulniers  * to do something like:
13f0907827SRasmus Villemoes  *
14f0907827SRasmus Villemoes  * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0)
15f0907827SRasmus Villemoes  * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0)
16f0907827SRasmus Villemoes  *
17f0907827SRasmus Villemoes  * Unfortunately, the middle expressions, strictly speaking, have
18f0907827SRasmus Villemoes  * undefined behaviour, and at least some versions of gcc warn about
19f0907827SRasmus Villemoes  * the type_max expression (but not if -fsanitize=undefined is in
20f0907827SRasmus Villemoes  * effect; in that case, the warning is deferred to runtime...).
21f0907827SRasmus Villemoes  *
22f0907827SRasmus Villemoes  * The slightly excessive casting in type_min is to make sure the
23f0907827SRasmus Villemoes  * macros also produce sensible values for the exotic type _Bool. [The
24f0907827SRasmus Villemoes  * overflow checkers only almost work for _Bool, but that's
25f0907827SRasmus Villemoes  * a-feature-not-a-bug, since people shouldn't be doing arithmetic on
26f0907827SRasmus Villemoes  * _Bools. Besides, the gcc builtins don't allow _Bool* as third
27f0907827SRasmus Villemoes  * argument.]
28f0907827SRasmus Villemoes  *
29f0907827SRasmus Villemoes  * Idea stolen from
30f0907827SRasmus Villemoes  * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html -
31f0907827SRasmus Villemoes  * credit to Christian Biere.
32f0907827SRasmus Villemoes  */
33f0907827SRasmus Villemoes #define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
34bd1ebf24SKees Cook #define __type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
35bd1ebf24SKees Cook #define type_max(t)	__type_max(typeof(t))
36bd1ebf24SKees Cook #define __type_min(T) ((T)((T)-type_max(T)-(T)1))
37bd1ebf24SKees Cook #define type_min(t)	__type_min(typeof(t))
38f0907827SRasmus Villemoes 
39dc7fe518SLeon Romanovsky /*
40dc7fe518SLeon Romanovsky  * Avoids triggering -Wtype-limits compilation warning,
41dc7fe518SLeon Romanovsky  * while using unsigned data types to check a < 0.
42dc7fe518SLeon Romanovsky  */
43dc7fe518SLeon Romanovsky #define is_non_negative(a) ((a) > 0 || (a) == 0)
44dc7fe518SLeon Romanovsky #define is_negative(a) (!(is_non_negative(a)))
45f0907827SRasmus Villemoes 
469b80e4c4SKees Cook /*
479b80e4c4SKees Cook  * Allows for effectively applying __must_check to a macro so we can have
489b80e4c4SKees Cook  * both the type-agnostic benefits of the macros while also being able to
499b80e4c4SKees Cook  * enforce that the return value is, in fact, checked.
509b80e4c4SKees Cook  */
__must_check_overflow(bool overflow)519b80e4c4SKees Cook static inline bool __must_check __must_check_overflow(bool overflow)
529b80e4c4SKees Cook {
539b80e4c4SKees Cook 	return unlikely(overflow);
549b80e4c4SKees Cook }
559b80e4c4SKees Cook 
5631970608SKees Cook /**
5731970608SKees Cook  * check_add_overflow() - Calculate addition with overflow checking
58d219d2a9SKees Cook  * @a: first addend
59d219d2a9SKees Cook  * @b: second addend
60d219d2a9SKees Cook  * @d: pointer to store sum
61d219d2a9SKees Cook  *
623e19086fSKees Cook  * Returns true on wrap-around, false otherwise.
63d219d2a9SKees Cook  *
643e19086fSKees Cook  * *@d holds the results of the attempted addition, regardless of whether
653e19086fSKees Cook  * wrap-around occurred.
66f0907827SRasmus Villemoes  */
67d219d2a9SKees Cook #define check_add_overflow(a, b, d)	\
68d219d2a9SKees Cook 	__must_check_overflow(__builtin_add_overflow(a, b, d))
69f0907827SRasmus Villemoes 
7031970608SKees Cook /**
71d70de805SKees Cook  * wrapping_add() - Intentionally perform a wrapping addition
72d70de805SKees Cook  * @type: type for result of calculation
73d70de805SKees Cook  * @a: first addend
74d70de805SKees Cook  * @b: second addend
75d70de805SKees Cook  *
76d70de805SKees Cook  * Return the potentially wrapped-around addition without
77d70de805SKees Cook  * tripping any wrap-around sanitizers that may be enabled.
78d70de805SKees Cook  */
79d70de805SKees Cook #define wrapping_add(type, a, b)				\
80d70de805SKees Cook 	({							\
81d70de805SKees Cook 		type __val;					\
82d70de805SKees Cook 		__builtin_add_overflow(a, b, &__val);		\
83d70de805SKees Cook 		__val;						\
84d70de805SKees Cook 	})
85d70de805SKees Cook 
86d70de805SKees Cook /**
8708d45ee8SKees Cook  * wrapping_assign_add() - Intentionally perform a wrapping increment assignment
8808d45ee8SKees Cook  * @var: variable to be incremented
8908d45ee8SKees Cook  * @offset: amount to add
9008d45ee8SKees Cook  *
9108d45ee8SKees Cook  * Increments @var by @offset with wrap-around. Returns the resulting
9208d45ee8SKees Cook  * value of @var. Will not trip any wrap-around sanitizers.
9308d45ee8SKees Cook  *
9408d45ee8SKees Cook  * Returns the new value of @var.
9508d45ee8SKees Cook  */
9608d45ee8SKees Cook #define wrapping_assign_add(var, offset)				\
9708d45ee8SKees Cook 	({								\
9808d45ee8SKees Cook 		typeof(var) *__ptr = &(var);				\
9908d45ee8SKees Cook 		*__ptr = wrapping_add(typeof(var), *__ptr, offset);	\
10008d45ee8SKees Cook 	})
10108d45ee8SKees Cook 
10208d45ee8SKees Cook /**
10331970608SKees Cook  * check_sub_overflow() - Calculate subtraction with overflow checking
104d219d2a9SKees Cook  * @a: minuend; value to subtract from
105d219d2a9SKees Cook  * @b: subtrahend; value to subtract from @a
106d219d2a9SKees Cook  * @d: pointer to store difference
107d219d2a9SKees Cook  *
1083e19086fSKees Cook  * Returns true on wrap-around, false otherwise.
109d219d2a9SKees Cook  *
1103e19086fSKees Cook  * *@d holds the results of the attempted subtraction, regardless of whether
1113e19086fSKees Cook  * wrap-around occurred.
112d219d2a9SKees Cook  */
113d219d2a9SKees Cook #define check_sub_overflow(a, b, d)	\
114d219d2a9SKees Cook 	__must_check_overflow(__builtin_sub_overflow(a, b, d))
115f0907827SRasmus Villemoes 
11631970608SKees Cook /**
117d70de805SKees Cook  * wrapping_sub() - Intentionally perform a wrapping subtraction
118d70de805SKees Cook  * @type: type for result of calculation
119d70de805SKees Cook  * @a: minuend; value to subtract from
120d70de805SKees Cook  * @b: subtrahend; value to subtract from @a
121d70de805SKees Cook  *
122d70de805SKees Cook  * Return the potentially wrapped-around subtraction without
123d70de805SKees Cook  * tripping any wrap-around sanitizers that may be enabled.
124d70de805SKees Cook  */
125d70de805SKees Cook #define wrapping_sub(type, a, b)				\
126d70de805SKees Cook 	({							\
127d70de805SKees Cook 		type __val;					\
128d70de805SKees Cook 		__builtin_sub_overflow(a, b, &__val);		\
129d70de805SKees Cook 		__val;						\
130d70de805SKees Cook 	})
131d70de805SKees Cook 
132d70de805SKees Cook /**
13308d45ee8SKees Cook  * wrapping_assign_sub() - Intentionally perform a wrapping decrement assign
13408d45ee8SKees Cook  * @var: variable to be decremented
13508d45ee8SKees Cook  * @offset: amount to subtract
13608d45ee8SKees Cook  *
13708d45ee8SKees Cook  * Decrements @var by @offset with wrap-around. Returns the resulting
13808d45ee8SKees Cook  * value of @var. Will not trip any wrap-around sanitizers.
13908d45ee8SKees Cook  *
14008d45ee8SKees Cook  * Returns the new value of @var.
14108d45ee8SKees Cook  */
14208d45ee8SKees Cook #define wrapping_assign_sub(var, offset)				\
14308d45ee8SKees Cook 	({								\
14408d45ee8SKees Cook 		typeof(var) *__ptr = &(var);				\
14508d45ee8SKees Cook 		*__ptr = wrapping_sub(typeof(var), *__ptr, offset);	\
14608d45ee8SKees Cook 	})
14708d45ee8SKees Cook 
14808d45ee8SKees Cook /**
14931970608SKees Cook  * check_mul_overflow() - Calculate multiplication with overflow checking
150d219d2a9SKees Cook  * @a: first factor
151d219d2a9SKees Cook  * @b: second factor
152d219d2a9SKees Cook  * @d: pointer to store product
153d219d2a9SKees Cook  *
1543e19086fSKees Cook  * Returns true on wrap-around, false otherwise.
155d219d2a9SKees Cook  *
1563e19086fSKees Cook  * *@d holds the results of the attempted multiplication, regardless of whether
1573e19086fSKees Cook  * wrap-around occurred.
158d219d2a9SKees Cook  */
159d219d2a9SKees Cook #define check_mul_overflow(a, b, d)	\
160d219d2a9SKees Cook 	__must_check_overflow(__builtin_mul_overflow(a, b, d))
161f0907827SRasmus Villemoes 
16231970608SKees Cook /**
163d70de805SKees Cook  * wrapping_mul() - Intentionally perform a wrapping multiplication
164d70de805SKees Cook  * @type: type for result of calculation
165d70de805SKees Cook  * @a: first factor
166d70de805SKees Cook  * @b: second factor
167d70de805SKees Cook  *
168d70de805SKees Cook  * Return the potentially wrapped-around multiplication without
169d70de805SKees Cook  * tripping any wrap-around sanitizers that may be enabled.
170d70de805SKees Cook  */
171d70de805SKees Cook #define wrapping_mul(type, a, b)				\
172d70de805SKees Cook 	({							\
173d70de805SKees Cook 		type __val;					\
174d70de805SKees Cook 		__builtin_mul_overflow(a, b, &__val);		\
175d70de805SKees Cook 		__val;						\
176d70de805SKees Cook 	})
177d70de805SKees Cook 
178d70de805SKees Cook /**
17931970608SKees Cook  * check_shl_overflow() - Calculate a left-shifted value and check overflow
1800c668477SJason Gunthorpe  * @a: Value to be shifted
1810c668477SJason Gunthorpe  * @s: How many bits left to shift
1820c668477SJason Gunthorpe  * @d: Pointer to where to store the result
1830c668477SJason Gunthorpe  *
1840c668477SJason Gunthorpe  * Computes *@d = (@a << @s)
1850c668477SJason Gunthorpe  *
18631970608SKees Cook  * Returns true if '*@d' cannot hold the result or when '@a << @s' doesn't
1870c668477SJason Gunthorpe  * make sense. Example conditions:
1880c668477SJason Gunthorpe  *
18931970608SKees Cook  * - '@a << @s' causes bits to be lost when stored in *@d.
19031970608SKees Cook  * - '@s' is garbage (e.g. negative) or so large that the result of
19131970608SKees Cook  *   '@a << @s' is guaranteed to be 0.
19231970608SKees Cook  * - '@a' is negative.
19331970608SKees Cook  * - '@a << @s' sets the sign bit, if any, in '*@d'.
19431970608SKees Cook  *
19531970608SKees Cook  * '*@d' will hold the results of the attempted shift, but is not
1964578be13SKeith Busch  * considered "safe for use" if true is returned.
1970c668477SJason Gunthorpe  */
1989b80e4c4SKees Cook #define check_shl_overflow(a, s, d) __must_check_overflow(({		\
1990c668477SJason Gunthorpe 	typeof(a) _a = a;						\
2000c668477SJason Gunthorpe 	typeof(s) _s = s;						\
2010c668477SJason Gunthorpe 	typeof(d) _d = d;						\
202c5e6d3d8SAndy Shevchenko 	unsigned long long _a_full = _a;				\
2030c668477SJason Gunthorpe 	unsigned int _to_shift =					\
204dc7fe518SLeon Romanovsky 		is_non_negative(_s) && _s < 8 * sizeof(*d) ? _s : 0;	\
2050c668477SJason Gunthorpe 	*_d = (_a_full << _to_shift);					\
206dc7fe518SLeon Romanovsky 	(_to_shift != _s || is_negative(*_d) || is_negative(_a) ||	\
2070c668477SJason Gunthorpe 	(*_d >> _to_shift) != _a);					\
2089b80e4c4SKees Cook }))
2090c668477SJason Gunthorpe 
2104b21d25bSKees Cook #define __overflows_type_constexpr(x, T) (			\
2114b21d25bSKees Cook 	is_unsigned_type(typeof(x)) ?				\
212bd1ebf24SKees Cook 		(x) > type_max(T) :				\
2134b21d25bSKees Cook 	is_unsigned_type(typeof(T)) ?				\
214bd1ebf24SKees Cook 		(x) < 0 || (x) > type_max(T) :			\
215bd1ebf24SKees Cook 	(x) < type_min(T) || (x) > type_max(T))
2164b21d25bSKees Cook 
2174b21d25bSKees Cook #define __overflows_type(x, T)		({	\
2184b21d25bSKees Cook 	typeof(T) v = 0;			\
2194b21d25bSKees Cook 	check_add_overflow((x), v, &v);		\
2204b21d25bSKees Cook })
2214b21d25bSKees Cook 
2224b21d25bSKees Cook /**
2234b21d25bSKees Cook  * overflows_type - helper for checking the overflows between value, variables,
2244b21d25bSKees Cook  *		    or data type
2254b21d25bSKees Cook  *
2264b21d25bSKees Cook  * @n: source constant value or variable to be checked
2274b21d25bSKees Cook  * @T: destination variable or data type proposed to store @x
2284b21d25bSKees Cook  *
2294b21d25bSKees Cook  * Compares the @x expression for whether or not it can safely fit in
2304b21d25bSKees Cook  * the storage of the type in @T. @x and @T can have different types.
2314b21d25bSKees Cook  * If @x is a constant expression, this will also resolve to a constant
2324b21d25bSKees Cook  * expression.
2334b21d25bSKees Cook  *
2344b21d25bSKees Cook  * Returns: true if overflow can occur, false otherwise.
2354b21d25bSKees Cook  */
2364b21d25bSKees Cook #define overflows_type(n, T)					\
2374b21d25bSKees Cook 	__builtin_choose_expr(__is_constexpr(n),		\
2384b21d25bSKees Cook 			      __overflows_type_constexpr(n, T),	\
2394b21d25bSKees Cook 			      __overflows_type(n, T))
2404b21d25bSKees Cook 
2414b21d25bSKees Cook /**
2424b21d25bSKees Cook  * castable_to_type - like __same_type(), but also allows for casted literals
2434b21d25bSKees Cook  *
2444b21d25bSKees Cook  * @n: variable or constant value
2454b21d25bSKees Cook  * @T: variable or data type
2464b21d25bSKees Cook  *
2474b21d25bSKees Cook  * Unlike the __same_type() macro, this allows a constant value as the
2484b21d25bSKees Cook  * first argument. If this value would not overflow into an assignment
2494b21d25bSKees Cook  * of the second argument's type, it returns true. Otherwise, this falls
2504b21d25bSKees Cook  * back to __same_type().
2514b21d25bSKees Cook  */
2524b21d25bSKees Cook #define castable_to_type(n, T)						\
2534b21d25bSKees Cook 	__builtin_choose_expr(__is_constexpr(n),			\
2544b21d25bSKees Cook 			      !__overflows_type_constexpr(n, T),	\
2554b21d25bSKees Cook 			      __same_type(n, T))
2564b21d25bSKees Cook 
257610b15c5SKees Cook /**
258e1be43d9SKees Cook  * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
259e1be43d9SKees Cook  * @factor1: first factor
260e1be43d9SKees Cook  * @factor2: second factor
261e1be43d9SKees Cook  *
262e1be43d9SKees Cook  * Returns: calculate @factor1 * @factor2, both promoted to size_t,
263e1be43d9SKees Cook  * with any overflow causing the return value to be SIZE_MAX. The
264e1be43d9SKees Cook  * lvalue must be size_t to avoid implicit type conversion.
265e1be43d9SKees Cook  */
size_mul(size_t factor1,size_t factor2)266e1be43d9SKees Cook static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
267e1be43d9SKees Cook {
268e1be43d9SKees Cook 	size_t bytes;
269e1be43d9SKees Cook 
270e1be43d9SKees Cook 	if (check_mul_overflow(factor1, factor2, &bytes))
271e1be43d9SKees Cook 		return SIZE_MAX;
272e1be43d9SKees Cook 
273e1be43d9SKees Cook 	return bytes;
274e1be43d9SKees Cook }
275e1be43d9SKees Cook 
276e1be43d9SKees Cook /**
277e1be43d9SKees Cook  * size_add() - Calculate size_t addition with saturation at SIZE_MAX
278e1be43d9SKees Cook  * @addend1: first addend
279e1be43d9SKees Cook  * @addend2: second addend
280e1be43d9SKees Cook  *
281e1be43d9SKees Cook  * Returns: calculate @addend1 + @addend2, both promoted to size_t,
282e1be43d9SKees Cook  * with any overflow causing the return value to be SIZE_MAX. The
283e1be43d9SKees Cook  * lvalue must be size_t to avoid implicit type conversion.
284e1be43d9SKees Cook  */
size_add(size_t addend1,size_t addend2)285e1be43d9SKees Cook static inline size_t __must_check size_add(size_t addend1, size_t addend2)
286e1be43d9SKees Cook {
287e1be43d9SKees Cook 	size_t bytes;
288e1be43d9SKees Cook 
289e1be43d9SKees Cook 	if (check_add_overflow(addend1, addend2, &bytes))
290e1be43d9SKees Cook 		return SIZE_MAX;
291e1be43d9SKees Cook 
292e1be43d9SKees Cook 	return bytes;
293e1be43d9SKees Cook }
294e1be43d9SKees Cook 
295e1be43d9SKees Cook /**
296e1be43d9SKees Cook  * size_sub() - Calculate size_t subtraction with saturation at SIZE_MAX
297e1be43d9SKees Cook  * @minuend: value to subtract from
298e1be43d9SKees Cook  * @subtrahend: value to subtract from @minuend
299e1be43d9SKees Cook  *
300e1be43d9SKees Cook  * Returns: calculate @minuend - @subtrahend, both promoted to size_t,
301e1be43d9SKees Cook  * with any overflow causing the return value to be SIZE_MAX. For
302e1be43d9SKees Cook  * composition with the size_add() and size_mul() helpers, neither
303e1be43d9SKees Cook  * argument may be SIZE_MAX (or the result with be forced to SIZE_MAX).
304e1be43d9SKees Cook  * The lvalue must be size_t to avoid implicit type conversion.
305e1be43d9SKees Cook  */
size_sub(size_t minuend,size_t subtrahend)306e1be43d9SKees Cook static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
307e1be43d9SKees Cook {
308e1be43d9SKees Cook 	size_t bytes;
309e1be43d9SKees Cook 
310e1be43d9SKees Cook 	if (minuend == SIZE_MAX || subtrahend == SIZE_MAX ||
311e1be43d9SKees Cook 	    check_sub_overflow(minuend, subtrahend, &bytes))
312e1be43d9SKees Cook 		return SIZE_MAX;
313e1be43d9SKees Cook 
314e1be43d9SKees Cook 	return bytes;
315e1be43d9SKees Cook }
316e1be43d9SKees Cook 
317e1be43d9SKees Cook /**
318610b15c5SKees Cook  * array_size() - Calculate size of 2-dimensional array.
319610b15c5SKees Cook  * @a: dimension one
320610b15c5SKees Cook  * @b: dimension two
321610b15c5SKees Cook  *
322610b15c5SKees Cook  * Calculates size of 2-dimensional array: @a * @b.
323610b15c5SKees Cook  *
324610b15c5SKees Cook  * Returns: number of bytes needed to represent the array or SIZE_MAX on
325610b15c5SKees Cook  * overflow.
326610b15c5SKees Cook  */
327e1be43d9SKees Cook #define array_size(a, b)	size_mul(a, b)
328610b15c5SKees Cook 
329610b15c5SKees Cook /**
330610b15c5SKees Cook  * array3_size() - Calculate size of 3-dimensional array.
331610b15c5SKees Cook  * @a: dimension one
332610b15c5SKees Cook  * @b: dimension two
333610b15c5SKees Cook  * @c: dimension three
334610b15c5SKees Cook  *
335610b15c5SKees Cook  * Calculates size of 3-dimensional array: @a * @b * @c.
336610b15c5SKees Cook  *
337610b15c5SKees Cook  * Returns: number of bytes needed to represent the array or SIZE_MAX on
338610b15c5SKees Cook  * overflow.
339610b15c5SKees Cook  */
340e1be43d9SKees Cook #define array3_size(a, b, c)	size_mul(size_mul(a, b), c)
341610b15c5SKees Cook 
342b19d57d0SGustavo A. R. Silva /**
343b19d57d0SGustavo A. R. Silva  * flex_array_size() - Calculate size of a flexible array member
344b19d57d0SGustavo A. R. Silva  *                     within an enclosing structure.
345b19d57d0SGustavo A. R. Silva  * @p: Pointer to the structure.
346b19d57d0SGustavo A. R. Silva  * @member: Name of the flexible array member.
347b19d57d0SGustavo A. R. Silva  * @count: Number of elements in the array.
348b19d57d0SGustavo A. R. Silva  *
349b19d57d0SGustavo A. R. Silva  * Calculates size of a flexible array of @count number of @member
350b19d57d0SGustavo A. R. Silva  * elements, at the end of structure @p.
351b19d57d0SGustavo A. R. Silva  *
352b19d57d0SGustavo A. R. Silva  * Return: number of bytes needed or SIZE_MAX on overflow.
353b19d57d0SGustavo A. R. Silva  */
354b19d57d0SGustavo A. R. Silva #define flex_array_size(p, member, count)				\
355230f6fa2SKees Cook 	__builtin_choose_expr(__is_constexpr(count),			\
356230f6fa2SKees Cook 		(count) * sizeof(*(p)->member) + __must_be_array((p)->member),	\
357230f6fa2SKees Cook 		size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member)))
358b19d57d0SGustavo A. R. Silva 
359e1be43d9SKees Cook /**
360e1be43d9SKees Cook  * struct_size() - Calculate size of structure with trailing flexible array.
361e1be43d9SKees Cook  * @p: Pointer to the structure.
362e1be43d9SKees Cook  * @member: Name of the array member.
363e1be43d9SKees Cook  * @count: Number of elements in the array.
364e1be43d9SKees Cook  *
365d67790ddSKees Cook  * Calculates size of memory needed for structure of @p followed by an
366e1be43d9SKees Cook  * array of @count number of @member elements.
367e1be43d9SKees Cook  *
368e1be43d9SKees Cook  * Return: number of bytes needed or SIZE_MAX on overflow.
369e1be43d9SKees Cook  */
370e1be43d9SKees Cook #define struct_size(p, member, count)					\
371230f6fa2SKees Cook 	__builtin_choose_expr(__is_constexpr(count),			\
372230f6fa2SKees Cook 		sizeof(*(p)) + flex_array_size(p, member, count),	\
373230f6fa2SKees Cook 		size_add(sizeof(*(p)), flex_array_size(p, member, count)))
374e1be43d9SKees Cook 
375d67790ddSKees Cook /**
376d67790ddSKees Cook  * struct_size_t() - Calculate size of structure with trailing flexible array
377d67790ddSKees Cook  * @type: structure type name.
378d67790ddSKees Cook  * @member: Name of the array member.
379d67790ddSKees Cook  * @count: Number of elements in the array.
380d67790ddSKees Cook  *
381d67790ddSKees Cook  * Calculates size of memory needed for structure @type followed by an
382d67790ddSKees Cook  * array of @count number of @member elements. Prefer using struct_size()
383d67790ddSKees Cook  * when possible instead, to keep calculations associated with a specific
384d67790ddSKees Cook  * instance variable of type @type.
385d67790ddSKees Cook  *
386d67790ddSKees Cook  * Return: number of bytes needed or SIZE_MAX on overflow.
387d67790ddSKees Cook  */
388d67790ddSKees Cook #define struct_size_t(type, member, count)					\
389d67790ddSKees Cook 	struct_size((type *)NULL, member, count)
390d67790ddSKees Cook 
39126dd68d2SPrzemek Kitszel /**
39226dd68d2SPrzemek Kitszel  * _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
39326dd68d2SPrzemek Kitszel  * Enables caller macro to pass (different) initializer.
39426dd68d2SPrzemek Kitszel  *
39526dd68d2SPrzemek Kitszel  * @type: structure type name, including "struct" keyword.
39626dd68d2SPrzemek Kitszel  * @name: Name for a variable to define.
39726dd68d2SPrzemek Kitszel  * @member: Name of the array member.
39826dd68d2SPrzemek Kitszel  * @count: Number of elements in the array; must be compile-time const.
39926dd68d2SPrzemek Kitszel  * @initializer: initializer expression (could be empty for no init).
40026dd68d2SPrzemek Kitszel  */
401*d8e45f29SKees Cook #define _DEFINE_FLEX(type, name, member, count, initializer...)			\
40226dd68d2SPrzemek Kitszel 	_Static_assert(__builtin_constant_p(count),				\
40326dd68d2SPrzemek Kitszel 		       "onstack flex array members require compile-time const count"); \
40426dd68d2SPrzemek Kitszel 	union {									\
40526dd68d2SPrzemek Kitszel 		u8 bytes[struct_size_t(type, member, count)];			\
40626dd68d2SPrzemek Kitszel 		type obj;							\
40726dd68d2SPrzemek Kitszel 	} name##_u initializer;							\
40826dd68d2SPrzemek Kitszel 	type *name = (type *)&name##_u
40926dd68d2SPrzemek Kitszel 
41026dd68d2SPrzemek Kitszel /**
411*d8e45f29SKees Cook  * DEFINE_RAW_FLEX() - Define an on-stack instance of structure with a trailing
412*d8e45f29SKees Cook  * flexible array member, when it does not have a __counted_by annotation.
41326dd68d2SPrzemek Kitszel  *
41426dd68d2SPrzemek Kitszel  * @type: structure type name, including "struct" keyword.
41526dd68d2SPrzemek Kitszel  * @name: Name for a variable to define.
41626dd68d2SPrzemek Kitszel  * @member: Name of the array member.
41726dd68d2SPrzemek Kitszel  * @count: Number of elements in the array; must be compile-time const.
41826dd68d2SPrzemek Kitszel  *
41926dd68d2SPrzemek Kitszel  * Define a zeroed, on-stack, instance of @type structure with a trailing
42026dd68d2SPrzemek Kitszel  * flexible array member.
42126dd68d2SPrzemek Kitszel  * Use __struct_size(@name) to get compile-time size of it afterwards.
42226dd68d2SPrzemek Kitszel  */
423*d8e45f29SKees Cook #define DEFINE_RAW_FLEX(type, name, member, count)	\
42426dd68d2SPrzemek Kitszel 	_DEFINE_FLEX(type, name, member, count, = {})
42526dd68d2SPrzemek Kitszel 
426*d8e45f29SKees Cook /**
427*d8e45f29SKees Cook  * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing
428*d8e45f29SKees Cook  * flexible array member.
429*d8e45f29SKees Cook  *
430*d8e45f29SKees Cook  * @TYPE: structure type name, including "struct" keyword.
431*d8e45f29SKees Cook  * @NAME: Name for a variable to define.
432*d8e45f29SKees Cook  * @MEMBER: Name of the array member.
433*d8e45f29SKees Cook  * @COUNTER: Name of the __counted_by member.
434*d8e45f29SKees Cook  * @COUNT: Number of elements in the array; must be compile-time const.
435*d8e45f29SKees Cook  *
436*d8e45f29SKees Cook  * Define a zeroed, on-stack, instance of @TYPE structure with a trailing
437*d8e45f29SKees Cook  * flexible array member.
438*d8e45f29SKees Cook  * Use __struct_size(@NAME) to get compile-time size of it afterwards.
439*d8e45f29SKees Cook  */
440*d8e45f29SKees Cook #define DEFINE_FLEX(TYPE, NAME, MEMBER, COUNTER, COUNT)	\
441*d8e45f29SKees Cook 	_DEFINE_FLEX(TYPE, NAME, MEMBER, COUNT, = { .obj.COUNTER = COUNT, })
442*d8e45f29SKees Cook 
443f0907827SRasmus Villemoes #endif /* __LINUX_OVERFLOW_H */
444