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