1617f55e2SKees Cook // SPDX-License-Identifier: GPL-2.0 OR MIT
2617f55e2SKees Cook /*
3617f55e2SKees Cook * Test cases for arithmetic overflow checks. See:
40f3f1123STales Aparecida * "Running tests with kunit_tool" at Documentation/dev-tools/kunit/start.rst
5617f55e2SKees Cook * ./tools/testing/kunit/kunit.py run overflow [--raw_output]
6617f55e2SKees Cook */
7617f55e2SKees Cook #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8617f55e2SKees Cook
9617f55e2SKees Cook #include <kunit/test.h>
10617f55e2SKees Cook #include <linux/device.h>
11617f55e2SKees Cook #include <linux/kernel.h>
12617f55e2SKees Cook #include <linux/mm.h>
13617f55e2SKees Cook #include <linux/module.h>
14617f55e2SKees Cook #include <linux/overflow.h>
15617f55e2SKees Cook #include <linux/slab.h>
16617f55e2SKees Cook #include <linux/types.h>
17617f55e2SKees Cook #include <linux/vmalloc.h>
18617f55e2SKees Cook
1972c3ebeaSKees Cook #define SKIP(cond, reason) do { \
2072c3ebeaSKees Cook if (cond) { \
2172c3ebeaSKees Cook kunit_skip(test, reason); \
2272c3ebeaSKees Cook return; \
2372c3ebeaSKees Cook } \
2472c3ebeaSKees Cook } while (0)
2572c3ebeaSKees Cook
2672c3ebeaSKees Cook /*
2772c3ebeaSKees Cook * Clang 11 and earlier generate unwanted libcalls for signed output
2872c3ebeaSKees Cook * on unsigned input.
2972c3ebeaSKees Cook */
3072c3ebeaSKees Cook #if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 11
3172c3ebeaSKees Cook # define SKIP_SIGN_MISMATCH(t) SKIP(t, "Clang 11 unwanted libcalls")
3272c3ebeaSKees Cook #else
3372c3ebeaSKees Cook # define SKIP_SIGN_MISMATCH(t) do { } while (0)
3472c3ebeaSKees Cook #endif
3572c3ebeaSKees Cook
3672c3ebeaSKees Cook /*
3772c3ebeaSKees Cook * Clang 13 and earlier generate unwanted libcalls for 64-bit tests on
3872c3ebeaSKees Cook * 32-bit hosts.
3972c3ebeaSKees Cook */
4072c3ebeaSKees Cook #if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 13 && \
4172c3ebeaSKees Cook BITS_PER_LONG != 64
4272c3ebeaSKees Cook # define SKIP_64_ON_32(t) SKIP(t, "Clang 13 unwanted libcalls")
4372c3ebeaSKees Cook #else
4472c3ebeaSKees Cook # define SKIP_64_ON_32(t) do { } while (0)
4572c3ebeaSKees Cook #endif
4672c3ebeaSKees Cook
47d219d2a9SKees Cook #define DEFINE_TEST_ARRAY_TYPED(t1, t2, t) \
48d219d2a9SKees Cook static const struct test_ ## t1 ## _ ## t2 ## __ ## t { \
49d219d2a9SKees Cook t1 a; \
50d219d2a9SKees Cook t2 b; \
51617f55e2SKees Cook t sum, diff, prod; \
52617f55e2SKees Cook bool s_of, d_of, p_of; \
53d219d2a9SKees Cook } t1 ## _ ## t2 ## __ ## t ## _tests[]
54d219d2a9SKees Cook
55d219d2a9SKees Cook #define DEFINE_TEST_ARRAY(t) DEFINE_TEST_ARRAY_TYPED(t, t, t)
56617f55e2SKees Cook
57617f55e2SKees Cook DEFINE_TEST_ARRAY(u8) = {
58617f55e2SKees Cook {0, 0, 0, 0, 0, false, false, false},
59617f55e2SKees Cook {1, 1, 2, 0, 1, false, false, false},
60617f55e2SKees Cook {0, 1, 1, U8_MAX, 0, false, true, false},
61617f55e2SKees Cook {1, 0, 1, 1, 0, false, false, false},
62617f55e2SKees Cook {0, U8_MAX, U8_MAX, 1, 0, false, true, false},
63617f55e2SKees Cook {U8_MAX, 0, U8_MAX, U8_MAX, 0, false, false, false},
64617f55e2SKees Cook {1, U8_MAX, 0, 2, U8_MAX, true, true, false},
65617f55e2SKees Cook {U8_MAX, 1, 0, U8_MAX-1, U8_MAX, true, false, false},
66617f55e2SKees Cook {U8_MAX, U8_MAX, U8_MAX-1, 0, 1, true, false, true},
67617f55e2SKees Cook
68617f55e2SKees Cook {U8_MAX, U8_MAX-1, U8_MAX-2, 1, 2, true, false, true},
69617f55e2SKees Cook {U8_MAX-1, U8_MAX, U8_MAX-2, U8_MAX, 2, true, true, true},
70617f55e2SKees Cook
71617f55e2SKees Cook {1U << 3, 1U << 3, 1U << 4, 0, 1U << 6, false, false, false},
72617f55e2SKees Cook {1U << 4, 1U << 4, 1U << 5, 0, 0, false, false, true},
73617f55e2SKees Cook {1U << 4, 1U << 3, 3*(1U << 3), 1U << 3, 1U << 7, false, false, false},
74617f55e2SKees Cook {1U << 7, 1U << 7, 0, 0, 0, true, false, true},
75617f55e2SKees Cook
76617f55e2SKees Cook {48, 32, 80, 16, 0, false, false, true},
77617f55e2SKees Cook {128, 128, 0, 0, 0, true, false, true},
78617f55e2SKees Cook {123, 234, 101, 145, 110, true, true, true},
79617f55e2SKees Cook };
80617f55e2SKees Cook DEFINE_TEST_ARRAY(u16) = {
81617f55e2SKees Cook {0, 0, 0, 0, 0, false, false, false},
82617f55e2SKees Cook {1, 1, 2, 0, 1, false, false, false},
83617f55e2SKees Cook {0, 1, 1, U16_MAX, 0, false, true, false},
84617f55e2SKees Cook {1, 0, 1, 1, 0, false, false, false},
85617f55e2SKees Cook {0, U16_MAX, U16_MAX, 1, 0, false, true, false},
86617f55e2SKees Cook {U16_MAX, 0, U16_MAX, U16_MAX, 0, false, false, false},
87617f55e2SKees Cook {1, U16_MAX, 0, 2, U16_MAX, true, true, false},
88617f55e2SKees Cook {U16_MAX, 1, 0, U16_MAX-1, U16_MAX, true, false, false},
89617f55e2SKees Cook {U16_MAX, U16_MAX, U16_MAX-1, 0, 1, true, false, true},
90617f55e2SKees Cook
91617f55e2SKees Cook {U16_MAX, U16_MAX-1, U16_MAX-2, 1, 2, true, false, true},
92617f55e2SKees Cook {U16_MAX-1, U16_MAX, U16_MAX-2, U16_MAX, 2, true, true, true},
93617f55e2SKees Cook
94617f55e2SKees Cook {1U << 7, 1U << 7, 1U << 8, 0, 1U << 14, false, false, false},
95617f55e2SKees Cook {1U << 8, 1U << 8, 1U << 9, 0, 0, false, false, true},
96617f55e2SKees Cook {1U << 8, 1U << 7, 3*(1U << 7), 1U << 7, 1U << 15, false, false, false},
97617f55e2SKees Cook {1U << 15, 1U << 15, 0, 0, 0, true, false, true},
98617f55e2SKees Cook
99617f55e2SKees Cook {123, 234, 357, 65425, 28782, false, true, false},
100617f55e2SKees Cook {1234, 2345, 3579, 64425, 10146, false, true, true},
101617f55e2SKees Cook };
102617f55e2SKees Cook DEFINE_TEST_ARRAY(u32) = {
103617f55e2SKees Cook {0, 0, 0, 0, 0, false, false, false},
104617f55e2SKees Cook {1, 1, 2, 0, 1, false, false, false},
105617f55e2SKees Cook {0, 1, 1, U32_MAX, 0, false, true, false},
106617f55e2SKees Cook {1, 0, 1, 1, 0, false, false, false},
107617f55e2SKees Cook {0, U32_MAX, U32_MAX, 1, 0, false, true, false},
108617f55e2SKees Cook {U32_MAX, 0, U32_MAX, U32_MAX, 0, false, false, false},
109617f55e2SKees Cook {1, U32_MAX, 0, 2, U32_MAX, true, true, false},
110617f55e2SKees Cook {U32_MAX, 1, 0, U32_MAX-1, U32_MAX, true, false, false},
111617f55e2SKees Cook {U32_MAX, U32_MAX, U32_MAX-1, 0, 1, true, false, true},
112617f55e2SKees Cook
113617f55e2SKees Cook {U32_MAX, U32_MAX-1, U32_MAX-2, 1, 2, true, false, true},
114617f55e2SKees Cook {U32_MAX-1, U32_MAX, U32_MAX-2, U32_MAX, 2, true, true, true},
115617f55e2SKees Cook
116617f55e2SKees Cook {1U << 15, 1U << 15, 1U << 16, 0, 1U << 30, false, false, false},
117617f55e2SKees Cook {1U << 16, 1U << 16, 1U << 17, 0, 0, false, false, true},
118617f55e2SKees Cook {1U << 16, 1U << 15, 3*(1U << 15), 1U << 15, 1U << 31, false, false, false},
119617f55e2SKees Cook {1U << 31, 1U << 31, 0, 0, 0, true, false, true},
120617f55e2SKees Cook
121617f55e2SKees Cook {-2U, 1U, -1U, -3U, -2U, false, false, false},
122617f55e2SKees Cook {-4U, 5U, 1U, -9U, -20U, true, false, true},
123617f55e2SKees Cook };
124617f55e2SKees Cook
125617f55e2SKees Cook DEFINE_TEST_ARRAY(u64) = {
126617f55e2SKees Cook {0, 0, 0, 0, 0, false, false, false},
127617f55e2SKees Cook {1, 1, 2, 0, 1, false, false, false},
128617f55e2SKees Cook {0, 1, 1, U64_MAX, 0, false, true, false},
129617f55e2SKees Cook {1, 0, 1, 1, 0, false, false, false},
130617f55e2SKees Cook {0, U64_MAX, U64_MAX, 1, 0, false, true, false},
131617f55e2SKees Cook {U64_MAX, 0, U64_MAX, U64_MAX, 0, false, false, false},
132617f55e2SKees Cook {1, U64_MAX, 0, 2, U64_MAX, true, true, false},
133617f55e2SKees Cook {U64_MAX, 1, 0, U64_MAX-1, U64_MAX, true, false, false},
134617f55e2SKees Cook {U64_MAX, U64_MAX, U64_MAX-1, 0, 1, true, false, true},
135617f55e2SKees Cook
136617f55e2SKees Cook {U64_MAX, U64_MAX-1, U64_MAX-2, 1, 2, true, false, true},
137617f55e2SKees Cook {U64_MAX-1, U64_MAX, U64_MAX-2, U64_MAX, 2, true, true, true},
138617f55e2SKees Cook
139617f55e2SKees Cook {1ULL << 31, 1ULL << 31, 1ULL << 32, 0, 1ULL << 62, false, false, false},
140617f55e2SKees Cook {1ULL << 32, 1ULL << 32, 1ULL << 33, 0, 0, false, false, true},
141617f55e2SKees Cook {1ULL << 32, 1ULL << 31, 3*(1ULL << 31), 1ULL << 31, 1ULL << 63, false, false, false},
142617f55e2SKees Cook {1ULL << 63, 1ULL << 63, 0, 0, 0, true, false, true},
143617f55e2SKees Cook {1000000000ULL /* 10^9 */, 10000000000ULL /* 10^10 */,
144617f55e2SKees Cook 11000000000ULL, 18446744064709551616ULL, 10000000000000000000ULL,
145617f55e2SKees Cook false, true, false},
146617f55e2SKees Cook {-15ULL, 10ULL, -5ULL, -25ULL, -150ULL, false, false, true},
147617f55e2SKees Cook };
148617f55e2SKees Cook
149617f55e2SKees Cook DEFINE_TEST_ARRAY(s8) = {
150617f55e2SKees Cook {0, 0, 0, 0, 0, false, false, false},
151617f55e2SKees Cook
152617f55e2SKees Cook {0, S8_MAX, S8_MAX, -S8_MAX, 0, false, false, false},
153617f55e2SKees Cook {S8_MAX, 0, S8_MAX, S8_MAX, 0, false, false, false},
154617f55e2SKees Cook {0, S8_MIN, S8_MIN, S8_MIN, 0, false, true, false},
155617f55e2SKees Cook {S8_MIN, 0, S8_MIN, S8_MIN, 0, false, false, false},
156617f55e2SKees Cook
157617f55e2SKees Cook {-1, S8_MIN, S8_MAX, S8_MAX, S8_MIN, true, false, true},
158617f55e2SKees Cook {S8_MIN, -1, S8_MAX, -S8_MAX, S8_MIN, true, false, true},
159617f55e2SKees Cook {-1, S8_MAX, S8_MAX-1, S8_MIN, -S8_MAX, false, false, false},
160617f55e2SKees Cook {S8_MAX, -1, S8_MAX-1, S8_MIN, -S8_MAX, false, true, false},
161617f55e2SKees Cook {-1, -S8_MAX, S8_MIN, S8_MAX-1, S8_MAX, false, false, false},
162617f55e2SKees Cook {-S8_MAX, -1, S8_MIN, S8_MIN+2, S8_MAX, false, false, false},
163617f55e2SKees Cook
164617f55e2SKees Cook {1, S8_MIN, -S8_MAX, -S8_MAX, S8_MIN, false, true, false},
165617f55e2SKees Cook {S8_MIN, 1, -S8_MAX, S8_MAX, S8_MIN, false, true, false},
166617f55e2SKees Cook {1, S8_MAX, S8_MIN, S8_MIN+2, S8_MAX, true, false, false},
167617f55e2SKees Cook {S8_MAX, 1, S8_MIN, S8_MAX-1, S8_MAX, true, false, false},
168617f55e2SKees Cook
169617f55e2SKees Cook {S8_MIN, S8_MIN, 0, 0, 0, true, false, true},
170617f55e2SKees Cook {S8_MAX, S8_MAX, -2, 0, 1, true, false, true},
171617f55e2SKees Cook
172617f55e2SKees Cook {-4, -32, -36, 28, -128, false, false, true},
173617f55e2SKees Cook {-4, 32, 28, -36, -128, false, false, false},
174617f55e2SKees Cook };
175617f55e2SKees Cook
176617f55e2SKees Cook DEFINE_TEST_ARRAY(s16) = {
177617f55e2SKees Cook {0, 0, 0, 0, 0, false, false, false},
178617f55e2SKees Cook
179617f55e2SKees Cook {0, S16_MAX, S16_MAX, -S16_MAX, 0, false, false, false},
180617f55e2SKees Cook {S16_MAX, 0, S16_MAX, S16_MAX, 0, false, false, false},
181617f55e2SKees Cook {0, S16_MIN, S16_MIN, S16_MIN, 0, false, true, false},
182617f55e2SKees Cook {S16_MIN, 0, S16_MIN, S16_MIN, 0, false, false, false},
183617f55e2SKees Cook
184617f55e2SKees Cook {-1, S16_MIN, S16_MAX, S16_MAX, S16_MIN, true, false, true},
185617f55e2SKees Cook {S16_MIN, -1, S16_MAX, -S16_MAX, S16_MIN, true, false, true},
186617f55e2SKees Cook {-1, S16_MAX, S16_MAX-1, S16_MIN, -S16_MAX, false, false, false},
187617f55e2SKees Cook {S16_MAX, -1, S16_MAX-1, S16_MIN, -S16_MAX, false, true, false},
188617f55e2SKees Cook {-1, -S16_MAX, S16_MIN, S16_MAX-1, S16_MAX, false, false, false},
189617f55e2SKees Cook {-S16_MAX, -1, S16_MIN, S16_MIN+2, S16_MAX, false, false, false},
190617f55e2SKees Cook
191617f55e2SKees Cook {1, S16_MIN, -S16_MAX, -S16_MAX, S16_MIN, false, true, false},
192617f55e2SKees Cook {S16_MIN, 1, -S16_MAX, S16_MAX, S16_MIN, false, true, false},
193617f55e2SKees Cook {1, S16_MAX, S16_MIN, S16_MIN+2, S16_MAX, true, false, false},
194617f55e2SKees Cook {S16_MAX, 1, S16_MIN, S16_MAX-1, S16_MAX, true, false, false},
195617f55e2SKees Cook
196617f55e2SKees Cook {S16_MIN, S16_MIN, 0, 0, 0, true, false, true},
197617f55e2SKees Cook {S16_MAX, S16_MAX, -2, 0, 1, true, false, true},
198617f55e2SKees Cook };
199617f55e2SKees Cook DEFINE_TEST_ARRAY(s32) = {
200617f55e2SKees Cook {0, 0, 0, 0, 0, false, false, false},
201617f55e2SKees Cook
202617f55e2SKees Cook {0, S32_MAX, S32_MAX, -S32_MAX, 0, false, false, false},
203617f55e2SKees Cook {S32_MAX, 0, S32_MAX, S32_MAX, 0, false, false, false},
204617f55e2SKees Cook {0, S32_MIN, S32_MIN, S32_MIN, 0, false, true, false},
205617f55e2SKees Cook {S32_MIN, 0, S32_MIN, S32_MIN, 0, false, false, false},
206617f55e2SKees Cook
207617f55e2SKees Cook {-1, S32_MIN, S32_MAX, S32_MAX, S32_MIN, true, false, true},
208617f55e2SKees Cook {S32_MIN, -1, S32_MAX, -S32_MAX, S32_MIN, true, false, true},
209617f55e2SKees Cook {-1, S32_MAX, S32_MAX-1, S32_MIN, -S32_MAX, false, false, false},
210617f55e2SKees Cook {S32_MAX, -1, S32_MAX-1, S32_MIN, -S32_MAX, false, true, false},
211617f55e2SKees Cook {-1, -S32_MAX, S32_MIN, S32_MAX-1, S32_MAX, false, false, false},
212617f55e2SKees Cook {-S32_MAX, -1, S32_MIN, S32_MIN+2, S32_MAX, false, false, false},
213617f55e2SKees Cook
214617f55e2SKees Cook {1, S32_MIN, -S32_MAX, -S32_MAX, S32_MIN, false, true, false},
215617f55e2SKees Cook {S32_MIN, 1, -S32_MAX, S32_MAX, S32_MIN, false, true, false},
216617f55e2SKees Cook {1, S32_MAX, S32_MIN, S32_MIN+2, S32_MAX, true, false, false},
217617f55e2SKees Cook {S32_MAX, 1, S32_MIN, S32_MAX-1, S32_MAX, true, false, false},
218617f55e2SKees Cook
219617f55e2SKees Cook {S32_MIN, S32_MIN, 0, 0, 0, true, false, true},
220617f55e2SKees Cook {S32_MAX, S32_MAX, -2, 0, 1, true, false, true},
221617f55e2SKees Cook };
2226a022dd2SKees Cook
223617f55e2SKees Cook DEFINE_TEST_ARRAY(s64) = {
224617f55e2SKees Cook {0, 0, 0, 0, 0, false, false, false},
225617f55e2SKees Cook
226617f55e2SKees Cook {0, S64_MAX, S64_MAX, -S64_MAX, 0, false, false, false},
227617f55e2SKees Cook {S64_MAX, 0, S64_MAX, S64_MAX, 0, false, false, false},
228617f55e2SKees Cook {0, S64_MIN, S64_MIN, S64_MIN, 0, false, true, false},
229617f55e2SKees Cook {S64_MIN, 0, S64_MIN, S64_MIN, 0, false, false, false},
230617f55e2SKees Cook
231617f55e2SKees Cook {-1, S64_MIN, S64_MAX, S64_MAX, S64_MIN, true, false, true},
232617f55e2SKees Cook {S64_MIN, -1, S64_MAX, -S64_MAX, S64_MIN, true, false, true},
233617f55e2SKees Cook {-1, S64_MAX, S64_MAX-1, S64_MIN, -S64_MAX, false, false, false},
234617f55e2SKees Cook {S64_MAX, -1, S64_MAX-1, S64_MIN, -S64_MAX, false, true, false},
235617f55e2SKees Cook {-1, -S64_MAX, S64_MIN, S64_MAX-1, S64_MAX, false, false, false},
236617f55e2SKees Cook {-S64_MAX, -1, S64_MIN, S64_MIN+2, S64_MAX, false, false, false},
237617f55e2SKees Cook
238617f55e2SKees Cook {1, S64_MIN, -S64_MAX, -S64_MAX, S64_MIN, false, true, false},
239617f55e2SKees Cook {S64_MIN, 1, -S64_MAX, S64_MAX, S64_MIN, false, true, false},
240617f55e2SKees Cook {1, S64_MAX, S64_MIN, S64_MIN+2, S64_MAX, true, false, false},
241617f55e2SKees Cook {S64_MAX, 1, S64_MIN, S64_MAX-1, S64_MAX, true, false, false},
242617f55e2SKees Cook
243617f55e2SKees Cook {S64_MIN, S64_MIN, 0, 0, 0, true, false, true},
244617f55e2SKees Cook {S64_MAX, S64_MAX, -2, 0, 1, true, false, true},
245617f55e2SKees Cook
246617f55e2SKees Cook {-1, -1, -2, 0, 1, false, false, false},
247617f55e2SKees Cook {-1, -128, -129, 127, 128, false, false, false},
248617f55e2SKees Cook {-128, -1, -129, -127, 128, false, false, false},
249617f55e2SKees Cook {0, -S64_MAX, -S64_MAX, S64_MAX, 0, false, false, false},
250617f55e2SKees Cook };
251617f55e2SKees Cook
252617f55e2SKees Cook #define check_one_op(t, fmt, op, sym, a, b, r, of) do { \
253d219d2a9SKees Cook int _a_orig = a, _a_bump = a + 1; \
254d219d2a9SKees Cook int _b_orig = b, _b_bump = b + 1; \
255617f55e2SKees Cook bool _of; \
256d219d2a9SKees Cook t _r; \
257617f55e2SKees Cook \
258617f55e2SKees Cook _of = check_ ## op ## _overflow(a, b, &_r); \
259617f55e2SKees Cook KUNIT_EXPECT_EQ_MSG(test, _of, of, \
260617f55e2SKees Cook "expected "fmt" "sym" "fmt" to%s overflow (type %s)\n", \
261617f55e2SKees Cook a, b, of ? "" : " not", #t); \
262617f55e2SKees Cook KUNIT_EXPECT_EQ_MSG(test, _r, r, \
263617f55e2SKees Cook "expected "fmt" "sym" "fmt" == "fmt", got "fmt" (type %s)\n", \
264617f55e2SKees Cook a, b, r, _r, #t); \
265d219d2a9SKees Cook /* Check for internal macro side-effects. */ \
266d219d2a9SKees Cook _of = check_ ## op ## _overflow(_a_orig++, _b_orig++, &_r); \
267d219d2a9SKees Cook KUNIT_EXPECT_EQ_MSG(test, _a_orig, _a_bump, "Unexpected " #op " macro side-effect!\n"); \
268d219d2a9SKees Cook KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump, "Unexpected " #op " macro side-effect!\n"); \
269617f55e2SKees Cook } while (0)
270617f55e2SKees Cook
271d219d2a9SKees Cook #define DEFINE_TEST_FUNC_TYPED(n, t, fmt) \
272d219d2a9SKees Cook static void do_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
273617f55e2SKees Cook { \
274617f55e2SKees Cook check_one_op(t, fmt, add, "+", p->a, p->b, p->sum, p->s_of); \
275617f55e2SKees Cook check_one_op(t, fmt, add, "+", p->b, p->a, p->sum, p->s_of); \
276617f55e2SKees Cook check_one_op(t, fmt, sub, "-", p->a, p->b, p->diff, p->d_of); \
277617f55e2SKees Cook check_one_op(t, fmt, mul, "*", p->a, p->b, p->prod, p->p_of); \
278617f55e2SKees Cook check_one_op(t, fmt, mul, "*", p->b, p->a, p->prod, p->p_of); \
279617f55e2SKees Cook } \
280617f55e2SKees Cook \
281d219d2a9SKees Cook static void n ## _overflow_test(struct kunit *test) { \
282617f55e2SKees Cook unsigned i; \
283617f55e2SKees Cook \
28472c3ebeaSKees Cook SKIP_64_ON_32(__same_type(t, u64)); \
28572c3ebeaSKees Cook SKIP_64_ON_32(__same_type(t, s64)); \
28672c3ebeaSKees Cook SKIP_SIGN_MISMATCH(__same_type(n ## _tests[0].a, u32) && \
28772c3ebeaSKees Cook __same_type(n ## _tests[0].b, u32) && \
28872c3ebeaSKees Cook __same_type(n ## _tests[0].sum, int)); \
28972c3ebeaSKees Cook \
290d219d2a9SKees Cook for (i = 0; i < ARRAY_SIZE(n ## _tests); ++i) \
291d219d2a9SKees Cook do_test_ ## n(test, &n ## _tests[i]); \
292617f55e2SKees Cook kunit_info(test, "%zu %s arithmetic tests finished\n", \
293d219d2a9SKees Cook ARRAY_SIZE(n ## _tests), #n); \
294617f55e2SKees Cook }
295617f55e2SKees Cook
296d219d2a9SKees Cook #define DEFINE_TEST_FUNC(t, fmt) \
297d219d2a9SKees Cook DEFINE_TEST_FUNC_TYPED(t ## _ ## t ## __ ## t, t, fmt)
298d219d2a9SKees Cook
299617f55e2SKees Cook DEFINE_TEST_FUNC(u8, "%d");
300617f55e2SKees Cook DEFINE_TEST_FUNC(s8, "%d");
301617f55e2SKees Cook DEFINE_TEST_FUNC(u16, "%d");
302617f55e2SKees Cook DEFINE_TEST_FUNC(s16, "%d");
303617f55e2SKees Cook DEFINE_TEST_FUNC(u32, "%u");
304617f55e2SKees Cook DEFINE_TEST_FUNC(s32, "%d");
305617f55e2SKees Cook DEFINE_TEST_FUNC(u64, "%llu");
306617f55e2SKees Cook DEFINE_TEST_FUNC(s64, "%lld");
307617f55e2SKees Cook
308d219d2a9SKees Cook DEFINE_TEST_ARRAY_TYPED(u32, u32, u8) = {
309d219d2a9SKees Cook {0, 0, 0, 0, 0, false, false, false},
310d219d2a9SKees Cook {U8_MAX, 2, 1, U8_MAX - 2, U8_MAX - 1, true, false, true},
311d219d2a9SKees Cook {U8_MAX + 1, 0, 0, 0, 0, true, true, false},
312d219d2a9SKees Cook };
313d219d2a9SKees Cook DEFINE_TEST_FUNC_TYPED(u32_u32__u8, u8, "%d");
314d219d2a9SKees Cook
315d219d2a9SKees Cook DEFINE_TEST_ARRAY_TYPED(u32, u32, int) = {
316d219d2a9SKees Cook {0, 0, 0, 0, 0, false, false, false},
317d219d2a9SKees Cook {U32_MAX, 0, -1, -1, 0, true, true, false},
318d219d2a9SKees Cook };
319d219d2a9SKees Cook DEFINE_TEST_FUNC_TYPED(u32_u32__int, int, "%d");
320d219d2a9SKees Cook
321d219d2a9SKees Cook DEFINE_TEST_ARRAY_TYPED(u8, u8, int) = {
322d219d2a9SKees Cook {0, 0, 0, 0, 0, false, false, false},
323d219d2a9SKees Cook {U8_MAX, U8_MAX, 2 * U8_MAX, 0, U8_MAX * U8_MAX, false, false, false},
324d219d2a9SKees Cook {1, 2, 3, -1, 2, false, false, false},
325d219d2a9SKees Cook };
326d219d2a9SKees Cook DEFINE_TEST_FUNC_TYPED(u8_u8__int, int, "%d");
327d219d2a9SKees Cook
328d219d2a9SKees Cook DEFINE_TEST_ARRAY_TYPED(int, int, u8) = {
329d219d2a9SKees Cook {0, 0, 0, 0, 0, false, false, false},
330d219d2a9SKees Cook {1, 2, 3, U8_MAX, 2, false, true, false},
331d219d2a9SKees Cook {-1, 0, U8_MAX, U8_MAX, 0, true, true, false},
332d219d2a9SKees Cook };
333d219d2a9SKees Cook DEFINE_TEST_FUNC_TYPED(int_int__u8, u8, "%d");
334d219d2a9SKees Cook
335617f55e2SKees Cook /* Args are: value, shift, type, expected result, overflow expected */
336617f55e2SKees Cook #define TEST_ONE_SHIFT(a, s, t, expect, of) do { \
337617f55e2SKees Cook typeof(a) __a = (a); \
338617f55e2SKees Cook typeof(s) __s = (s); \
339617f55e2SKees Cook t __e = (expect); \
340617f55e2SKees Cook t __d; \
341617f55e2SKees Cook bool __of = check_shl_overflow(__a, __s, &__d); \
342617f55e2SKees Cook if (__of != of) { \
343617f55e2SKees Cook KUNIT_EXPECT_EQ_MSG(test, __of, of, \
344617f55e2SKees Cook "expected (%s)(%s << %s) to%s overflow\n", \
345617f55e2SKees Cook #t, #a, #s, of ? "" : " not"); \
346617f55e2SKees Cook } else if (!__of && __d != __e) { \
347617f55e2SKees Cook KUNIT_EXPECT_EQ_MSG(test, __d, __e, \
348617f55e2SKees Cook "expected (%s)(%s << %s) == %s\n", \
349617f55e2SKees Cook #t, #a, #s, #expect); \
350617f55e2SKees Cook if ((t)-1 < 0) \
351617f55e2SKees Cook kunit_info(test, "got %lld\n", (s64)__d); \
352617f55e2SKees Cook else \
353617f55e2SKees Cook kunit_info(test, "got %llu\n", (u64)__d); \
354617f55e2SKees Cook } \
355617f55e2SKees Cook count++; \
356617f55e2SKees Cook } while (0)
357617f55e2SKees Cook
shift_sane_test(struct kunit * test)35877974225SKees Cook static void shift_sane_test(struct kunit *test)
35977974225SKees Cook {
36077974225SKees Cook int count = 0;
36177974225SKees Cook
362617f55e2SKees Cook /* Sane shifts. */
363617f55e2SKees Cook TEST_ONE_SHIFT(1, 0, u8, 1 << 0, false);
364617f55e2SKees Cook TEST_ONE_SHIFT(1, 4, u8, 1 << 4, false);
365617f55e2SKees Cook TEST_ONE_SHIFT(1, 7, u8, 1 << 7, false);
366617f55e2SKees Cook TEST_ONE_SHIFT(0xF, 4, u8, 0xF << 4, false);
367617f55e2SKees Cook TEST_ONE_SHIFT(1, 0, u16, 1 << 0, false);
368617f55e2SKees Cook TEST_ONE_SHIFT(1, 10, u16, 1 << 10, false);
369617f55e2SKees Cook TEST_ONE_SHIFT(1, 15, u16, 1 << 15, false);
370617f55e2SKees Cook TEST_ONE_SHIFT(0xFF, 8, u16, 0xFF << 8, false);
371617f55e2SKees Cook TEST_ONE_SHIFT(1, 0, int, 1 << 0, false);
372617f55e2SKees Cook TEST_ONE_SHIFT(1, 16, int, 1 << 16, false);
373617f55e2SKees Cook TEST_ONE_SHIFT(1, 30, int, 1 << 30, false);
374617f55e2SKees Cook TEST_ONE_SHIFT(1, 0, s32, 1 << 0, false);
375617f55e2SKees Cook TEST_ONE_SHIFT(1, 16, s32, 1 << 16, false);
376617f55e2SKees Cook TEST_ONE_SHIFT(1, 30, s32, 1 << 30, false);
377617f55e2SKees Cook TEST_ONE_SHIFT(1, 0, unsigned int, 1U << 0, false);
378617f55e2SKees Cook TEST_ONE_SHIFT(1, 20, unsigned int, 1U << 20, false);
379617f55e2SKees Cook TEST_ONE_SHIFT(1, 31, unsigned int, 1U << 31, false);
380617f55e2SKees Cook TEST_ONE_SHIFT(0xFFFFU, 16, unsigned int, 0xFFFFU << 16, false);
381617f55e2SKees Cook TEST_ONE_SHIFT(1, 0, u32, 1U << 0, false);
382617f55e2SKees Cook TEST_ONE_SHIFT(1, 20, u32, 1U << 20, false);
383617f55e2SKees Cook TEST_ONE_SHIFT(1, 31, u32, 1U << 31, false);
384617f55e2SKees Cook TEST_ONE_SHIFT(0xFFFFU, 16, u32, 0xFFFFU << 16, false);
385617f55e2SKees Cook TEST_ONE_SHIFT(1, 0, u64, 1ULL << 0, false);
386617f55e2SKees Cook TEST_ONE_SHIFT(1, 40, u64, 1ULL << 40, false);
387617f55e2SKees Cook TEST_ONE_SHIFT(1, 63, u64, 1ULL << 63, false);
388617f55e2SKees Cook TEST_ONE_SHIFT(0xFFFFFFFFULL, 32, u64, 0xFFFFFFFFULL << 32, false);
389617f55e2SKees Cook
390617f55e2SKees Cook /* Sane shift: start and end with 0, without a too-wide shift. */
391617f55e2SKees Cook TEST_ONE_SHIFT(0, 7, u8, 0, false);
392617f55e2SKees Cook TEST_ONE_SHIFT(0, 15, u16, 0, false);
393617f55e2SKees Cook TEST_ONE_SHIFT(0, 31, unsigned int, 0, false);
394617f55e2SKees Cook TEST_ONE_SHIFT(0, 31, u32, 0, false);
395617f55e2SKees Cook TEST_ONE_SHIFT(0, 63, u64, 0, false);
396617f55e2SKees Cook
397617f55e2SKees Cook /* Sane shift: start and end with 0, without reaching signed bit. */
398617f55e2SKees Cook TEST_ONE_SHIFT(0, 6, s8, 0, false);
399617f55e2SKees Cook TEST_ONE_SHIFT(0, 14, s16, 0, false);
400617f55e2SKees Cook TEST_ONE_SHIFT(0, 30, int, 0, false);
401617f55e2SKees Cook TEST_ONE_SHIFT(0, 30, s32, 0, false);
402617f55e2SKees Cook TEST_ONE_SHIFT(0, 62, s64, 0, false);
403617f55e2SKees Cook
40477974225SKees Cook kunit_info(test, "%d sane shift tests finished\n", count);
40577974225SKees Cook }
40677974225SKees Cook
shift_overflow_test(struct kunit * test)40777974225SKees Cook static void shift_overflow_test(struct kunit *test)
40877974225SKees Cook {
40977974225SKees Cook int count = 0;
41077974225SKees Cook
411617f55e2SKees Cook /* Overflow: shifted the bit off the end. */
412617f55e2SKees Cook TEST_ONE_SHIFT(1, 8, u8, 0, true);
413617f55e2SKees Cook TEST_ONE_SHIFT(1, 16, u16, 0, true);
414617f55e2SKees Cook TEST_ONE_SHIFT(1, 32, unsigned int, 0, true);
415617f55e2SKees Cook TEST_ONE_SHIFT(1, 32, u32, 0, true);
416617f55e2SKees Cook TEST_ONE_SHIFT(1, 64, u64, 0, true);
417617f55e2SKees Cook
418617f55e2SKees Cook /* Overflow: shifted into the signed bit. */
419617f55e2SKees Cook TEST_ONE_SHIFT(1, 7, s8, 0, true);
420617f55e2SKees Cook TEST_ONE_SHIFT(1, 15, s16, 0, true);
421617f55e2SKees Cook TEST_ONE_SHIFT(1, 31, int, 0, true);
422617f55e2SKees Cook TEST_ONE_SHIFT(1, 31, s32, 0, true);
423617f55e2SKees Cook TEST_ONE_SHIFT(1, 63, s64, 0, true);
424617f55e2SKees Cook
425617f55e2SKees Cook /* Overflow: high bit falls off unsigned types. */
426617f55e2SKees Cook /* 10010110 */
427617f55e2SKees Cook TEST_ONE_SHIFT(150, 1, u8, 0, true);
428617f55e2SKees Cook /* 1000100010010110 */
429617f55e2SKees Cook TEST_ONE_SHIFT(34966, 1, u16, 0, true);
430617f55e2SKees Cook /* 10000100000010001000100010010110 */
431617f55e2SKees Cook TEST_ONE_SHIFT(2215151766U, 1, u32, 0, true);
432617f55e2SKees Cook TEST_ONE_SHIFT(2215151766U, 1, unsigned int, 0, true);
433617f55e2SKees Cook /* 1000001000010000010000000100000010000100000010001000100010010110 */
434617f55e2SKees Cook TEST_ONE_SHIFT(9372061470395238550ULL, 1, u64, 0, true);
435617f55e2SKees Cook
436617f55e2SKees Cook /* Overflow: bit shifted into signed bit on signed types. */
437617f55e2SKees Cook /* 01001011 */
438617f55e2SKees Cook TEST_ONE_SHIFT(75, 1, s8, 0, true);
439617f55e2SKees Cook /* 0100010001001011 */
440617f55e2SKees Cook TEST_ONE_SHIFT(17483, 1, s16, 0, true);
441617f55e2SKees Cook /* 01000010000001000100010001001011 */
442617f55e2SKees Cook TEST_ONE_SHIFT(1107575883, 1, s32, 0, true);
443617f55e2SKees Cook TEST_ONE_SHIFT(1107575883, 1, int, 0, true);
444617f55e2SKees Cook /* 0100000100001000001000000010000001000010000001000100010001001011 */
445617f55e2SKees Cook TEST_ONE_SHIFT(4686030735197619275LL, 1, s64, 0, true);
446617f55e2SKees Cook
447617f55e2SKees Cook /* Overflow: bit shifted past signed bit on signed types. */
448617f55e2SKees Cook /* 01001011 */
449617f55e2SKees Cook TEST_ONE_SHIFT(75, 2, s8, 0, true);
450617f55e2SKees Cook /* 0100010001001011 */
451617f55e2SKees Cook TEST_ONE_SHIFT(17483, 2, s16, 0, true);
452617f55e2SKees Cook /* 01000010000001000100010001001011 */
453617f55e2SKees Cook TEST_ONE_SHIFT(1107575883, 2, s32, 0, true);
454617f55e2SKees Cook TEST_ONE_SHIFT(1107575883, 2, int, 0, true);
455617f55e2SKees Cook /* 0100000100001000001000000010000001000010000001000100010001001011 */
456617f55e2SKees Cook TEST_ONE_SHIFT(4686030735197619275LL, 2, s64, 0, true);
457617f55e2SKees Cook
45877974225SKees Cook kunit_info(test, "%d overflow shift tests finished\n", count);
45977974225SKees Cook }
46077974225SKees Cook
shift_truncate_test(struct kunit * test)46177974225SKees Cook static void shift_truncate_test(struct kunit *test)
46277974225SKees Cook {
46377974225SKees Cook int count = 0;
46477974225SKees Cook
465617f55e2SKees Cook /* Overflow: values larger than destination type. */
466617f55e2SKees Cook TEST_ONE_SHIFT(0x100, 0, u8, 0, true);
467617f55e2SKees Cook TEST_ONE_SHIFT(0xFF, 0, s8, 0, true);
468617f55e2SKees Cook TEST_ONE_SHIFT(0x10000U, 0, u16, 0, true);
469617f55e2SKees Cook TEST_ONE_SHIFT(0xFFFFU, 0, s16, 0, true);
470617f55e2SKees Cook TEST_ONE_SHIFT(0x100000000ULL, 0, u32, 0, true);
471617f55e2SKees Cook TEST_ONE_SHIFT(0x100000000ULL, 0, unsigned int, 0, true);
472617f55e2SKees Cook TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, s32, 0, true);
473617f55e2SKees Cook TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, int, 0, true);
474617f55e2SKees Cook TEST_ONE_SHIFT(0xFFFFFFFFFFFFFFFFULL, 0, s64, 0, true);
475617f55e2SKees Cook
47677974225SKees Cook /* Overflow: shifted at or beyond entire type's bit width. */
47777974225SKees Cook TEST_ONE_SHIFT(0, 8, u8, 0, true);
47877974225SKees Cook TEST_ONE_SHIFT(0, 9, u8, 0, true);
47977974225SKees Cook TEST_ONE_SHIFT(0, 8, s8, 0, true);
48077974225SKees Cook TEST_ONE_SHIFT(0, 9, s8, 0, true);
48177974225SKees Cook TEST_ONE_SHIFT(0, 16, u16, 0, true);
48277974225SKees Cook TEST_ONE_SHIFT(0, 17, u16, 0, true);
48377974225SKees Cook TEST_ONE_SHIFT(0, 16, s16, 0, true);
48477974225SKees Cook TEST_ONE_SHIFT(0, 17, s16, 0, true);
48577974225SKees Cook TEST_ONE_SHIFT(0, 32, u32, 0, true);
48677974225SKees Cook TEST_ONE_SHIFT(0, 33, u32, 0, true);
48777974225SKees Cook TEST_ONE_SHIFT(0, 32, int, 0, true);
48877974225SKees Cook TEST_ONE_SHIFT(0, 33, int, 0, true);
48977974225SKees Cook TEST_ONE_SHIFT(0, 32, s32, 0, true);
49077974225SKees Cook TEST_ONE_SHIFT(0, 33, s32, 0, true);
49177974225SKees Cook TEST_ONE_SHIFT(0, 64, u64, 0, true);
49277974225SKees Cook TEST_ONE_SHIFT(0, 65, u64, 0, true);
49377974225SKees Cook TEST_ONE_SHIFT(0, 64, s64, 0, true);
49477974225SKees Cook TEST_ONE_SHIFT(0, 65, s64, 0, true);
49577974225SKees Cook
49677974225SKees Cook kunit_info(test, "%d truncate shift tests finished\n", count);
49777974225SKees Cook }
49877974225SKees Cook
shift_nonsense_test(struct kunit * test)49977974225SKees Cook static void shift_nonsense_test(struct kunit *test)
50077974225SKees Cook {
50177974225SKees Cook int count = 0;
50277974225SKees Cook
503617f55e2SKees Cook /* Nonsense: negative initial value. */
504617f55e2SKees Cook TEST_ONE_SHIFT(-1, 0, s8, 0, true);
505617f55e2SKees Cook TEST_ONE_SHIFT(-1, 0, u8, 0, true);
506617f55e2SKees Cook TEST_ONE_SHIFT(-5, 0, s16, 0, true);
507617f55e2SKees Cook TEST_ONE_SHIFT(-5, 0, u16, 0, true);
508617f55e2SKees Cook TEST_ONE_SHIFT(-10, 0, int, 0, true);
509617f55e2SKees Cook TEST_ONE_SHIFT(-10, 0, unsigned int, 0, true);
510617f55e2SKees Cook TEST_ONE_SHIFT(-100, 0, s32, 0, true);
511617f55e2SKees Cook TEST_ONE_SHIFT(-100, 0, u32, 0, true);
512617f55e2SKees Cook TEST_ONE_SHIFT(-10000, 0, s64, 0, true);
513617f55e2SKees Cook TEST_ONE_SHIFT(-10000, 0, u64, 0, true);
514617f55e2SKees Cook
515617f55e2SKees Cook /* Nonsense: negative shift values. */
516617f55e2SKees Cook TEST_ONE_SHIFT(0, -5, s8, 0, true);
517617f55e2SKees Cook TEST_ONE_SHIFT(0, -5, u8, 0, true);
518617f55e2SKees Cook TEST_ONE_SHIFT(0, -10, s16, 0, true);
519617f55e2SKees Cook TEST_ONE_SHIFT(0, -10, u16, 0, true);
520617f55e2SKees Cook TEST_ONE_SHIFT(0, -15, int, 0, true);
521617f55e2SKees Cook TEST_ONE_SHIFT(0, -15, unsigned int, 0, true);
522617f55e2SKees Cook TEST_ONE_SHIFT(0, -20, s32, 0, true);
523617f55e2SKees Cook TEST_ONE_SHIFT(0, -20, u32, 0, true);
524617f55e2SKees Cook TEST_ONE_SHIFT(0, -30, s64, 0, true);
525617f55e2SKees Cook TEST_ONE_SHIFT(0, -30, u64, 0, true);
526617f55e2SKees Cook
527617f55e2SKees Cook /*
528617f55e2SKees Cook * Corner case: for unsigned types, we fail when we've shifted
529617f55e2SKees Cook * through the entire width of bits. For signed types, we might
530617f55e2SKees Cook * want to match this behavior, but that would mean noticing if
531617f55e2SKees Cook * we shift through all but the signed bit, and this is not
532617f55e2SKees Cook * currently detected (but we'll notice an overflow into the
533617f55e2SKees Cook * signed bit). So, for now, we will test this condition but
534617f55e2SKees Cook * mark it as not expected to overflow.
535617f55e2SKees Cook */
536617f55e2SKees Cook TEST_ONE_SHIFT(0, 7, s8, 0, false);
537617f55e2SKees Cook TEST_ONE_SHIFT(0, 15, s16, 0, false);
538617f55e2SKees Cook TEST_ONE_SHIFT(0, 31, int, 0, false);
539617f55e2SKees Cook TEST_ONE_SHIFT(0, 31, s32, 0, false);
540617f55e2SKees Cook TEST_ONE_SHIFT(0, 63, s64, 0, false);
541617f55e2SKees Cook
54277974225SKees Cook kunit_info(test, "%d nonsense shift tests finished\n", count);
543617f55e2SKees Cook }
54477974225SKees Cook #undef TEST_ONE_SHIFT
545617f55e2SKees Cook
546617f55e2SKees Cook /*
547617f55e2SKees Cook * Deal with the various forms of allocator arguments. See comments above
548617f55e2SKees Cook * the DEFINE_TEST_ALLOC() instances for mapping of the "bits".
549617f55e2SKees Cook */
550617f55e2SKees Cook #define alloc_GFP (GFP_KERNEL | __GFP_NOWARN)
551617f55e2SKees Cook #define alloc010(alloc, arg, sz) alloc(sz, alloc_GFP)
552617f55e2SKees Cook #define alloc011(alloc, arg, sz) alloc(sz, alloc_GFP, NUMA_NO_NODE)
553617f55e2SKees Cook #define alloc000(alloc, arg, sz) alloc(sz)
554617f55e2SKees Cook #define alloc001(alloc, arg, sz) alloc(sz, NUMA_NO_NODE)
555617f55e2SKees Cook #define alloc110(alloc, arg, sz) alloc(arg, sz, alloc_GFP)
556617f55e2SKees Cook #define free0(free, arg, ptr) free(ptr)
557617f55e2SKees Cook #define free1(free, arg, ptr) free(arg, ptr)
558617f55e2SKees Cook
559617f55e2SKees Cook /* Wrap around to 16K */
560617f55e2SKees Cook #define TEST_SIZE (5 * 4096)
561617f55e2SKees Cook
562617f55e2SKees Cook #define DEFINE_TEST_ALLOC(func, free_func, want_arg, want_gfp, want_node)\
563617f55e2SKees Cook static void test_ ## func (struct kunit *test, void *arg) \
564617f55e2SKees Cook { \
565617f55e2SKees Cook volatile size_t a = TEST_SIZE; \
566617f55e2SKees Cook volatile size_t b = (SIZE_MAX / TEST_SIZE) + 1; \
567617f55e2SKees Cook void *ptr; \
568617f55e2SKees Cook \
569617f55e2SKees Cook /* Tiny allocation test. */ \
570617f55e2SKees Cook ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg, 1);\
571617f55e2SKees Cook KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr, \
572617f55e2SKees Cook #func " failed regular allocation?!\n"); \
573617f55e2SKees Cook free ## want_arg (free_func, arg, ptr); \
574617f55e2SKees Cook \
575617f55e2SKees Cook /* Wrapped allocation test. */ \
576617f55e2SKees Cook ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg, \
577617f55e2SKees Cook a * b); \
578617f55e2SKees Cook KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr, \
579617f55e2SKees Cook #func " unexpectedly failed bad wrapping?!\n"); \
580617f55e2SKees Cook free ## want_arg (free_func, arg, ptr); \
581617f55e2SKees Cook \
582617f55e2SKees Cook /* Saturated allocation test. */ \
583617f55e2SKees Cook ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg, \
584617f55e2SKees Cook array_size(a, b)); \
585617f55e2SKees Cook if (ptr) { \
586617f55e2SKees Cook KUNIT_FAIL(test, #func " missed saturation!\n"); \
587617f55e2SKees Cook free ## want_arg (free_func, arg, ptr); \
588617f55e2SKees Cook } \
589617f55e2SKees Cook }
590617f55e2SKees Cook
591617f55e2SKees Cook /*
592617f55e2SKees Cook * Allocator uses a trailing node argument --------+ (e.g. kmalloc_node())
593617f55e2SKees Cook * Allocator uses the gfp_t argument -----------+ | (e.g. kmalloc())
594617f55e2SKees Cook * Allocator uses a special leading argument + | | (e.g. devm_kmalloc())
595617f55e2SKees Cook * | | |
596617f55e2SKees Cook */
597617f55e2SKees Cook DEFINE_TEST_ALLOC(kmalloc, kfree, 0, 1, 0);
598617f55e2SKees Cook DEFINE_TEST_ALLOC(kmalloc_node, kfree, 0, 1, 1);
599617f55e2SKees Cook DEFINE_TEST_ALLOC(kzalloc, kfree, 0, 1, 0);
600617f55e2SKees Cook DEFINE_TEST_ALLOC(kzalloc_node, kfree, 0, 1, 1);
601617f55e2SKees Cook DEFINE_TEST_ALLOC(__vmalloc, vfree, 0, 1, 0);
602617f55e2SKees Cook DEFINE_TEST_ALLOC(kvmalloc, kvfree, 0, 1, 0);
603617f55e2SKees Cook DEFINE_TEST_ALLOC(kvmalloc_node, kvfree, 0, 1, 1);
604617f55e2SKees Cook DEFINE_TEST_ALLOC(kvzalloc, kvfree, 0, 1, 0);
605617f55e2SKees Cook DEFINE_TEST_ALLOC(kvzalloc_node, kvfree, 0, 1, 1);
606617f55e2SKees Cook DEFINE_TEST_ALLOC(devm_kmalloc, devm_kfree, 1, 1, 0);
607617f55e2SKees Cook DEFINE_TEST_ALLOC(devm_kzalloc, devm_kfree, 1, 1, 0);
608617f55e2SKees Cook
overflow_allocation_test(struct kunit * test)609617f55e2SKees Cook static void overflow_allocation_test(struct kunit *test)
610617f55e2SKees Cook {
611617f55e2SKees Cook const char device_name[] = "overflow-test";
612617f55e2SKees Cook struct device *dev;
613617f55e2SKees Cook int count = 0;
614617f55e2SKees Cook
615617f55e2SKees Cook #define check_allocation_overflow(alloc) do { \
616617f55e2SKees Cook count++; \
617617f55e2SKees Cook test_ ## alloc(test, dev); \
618617f55e2SKees Cook } while (0)
619617f55e2SKees Cook
620617f55e2SKees Cook /* Create dummy device for devm_kmalloc()-family tests. */
621617f55e2SKees Cook dev = root_device_register(device_name);
622617f55e2SKees Cook KUNIT_ASSERT_FALSE_MSG(test, IS_ERR(dev),
623617f55e2SKees Cook "Cannot register test device\n");
624617f55e2SKees Cook
625617f55e2SKees Cook check_allocation_overflow(kmalloc);
626617f55e2SKees Cook check_allocation_overflow(kmalloc_node);
627617f55e2SKees Cook check_allocation_overflow(kzalloc);
628617f55e2SKees Cook check_allocation_overflow(kzalloc_node);
629617f55e2SKees Cook check_allocation_overflow(__vmalloc);
630617f55e2SKees Cook check_allocation_overflow(kvmalloc);
631617f55e2SKees Cook check_allocation_overflow(kvmalloc_node);
632617f55e2SKees Cook check_allocation_overflow(kvzalloc);
633617f55e2SKees Cook check_allocation_overflow(kvzalloc_node);
634617f55e2SKees Cook check_allocation_overflow(devm_kmalloc);
635617f55e2SKees Cook check_allocation_overflow(devm_kzalloc);
636617f55e2SKees Cook
637617f55e2SKees Cook device_unregister(dev);
638617f55e2SKees Cook
639617f55e2SKees Cook kunit_info(test, "%d allocation overflow tests finished\n", count);
640617f55e2SKees Cook #undef check_allocation_overflow
641617f55e2SKees Cook }
642617f55e2SKees Cook
643617f55e2SKees Cook struct __test_flex_array {
644617f55e2SKees Cook unsigned long flags;
645617f55e2SKees Cook size_t count;
646617f55e2SKees Cook unsigned long data[];
647617f55e2SKees Cook };
648617f55e2SKees Cook
overflow_size_helpers_test(struct kunit * test)649617f55e2SKees Cook static void overflow_size_helpers_test(struct kunit *test)
650617f55e2SKees Cook {
651617f55e2SKees Cook /* Make sure struct_size() can be used in a constant expression. */
652*d67790ddSKees Cook u8 ce_array[struct_size_t(struct __test_flex_array, data, 55)];
653617f55e2SKees Cook struct __test_flex_array *obj;
654617f55e2SKees Cook int count = 0;
655617f55e2SKees Cook int var;
656617f55e2SKees Cook volatile int unconst = 0;
657617f55e2SKees Cook
658617f55e2SKees Cook /* Verify constant expression against runtime version. */
659617f55e2SKees Cook var = 55;
660617f55e2SKees Cook OPTIMIZER_HIDE_VAR(var);
661617f55e2SKees Cook KUNIT_EXPECT_EQ(test, sizeof(ce_array), struct_size(obj, data, var));
662617f55e2SKees Cook
663617f55e2SKees Cook #define check_one_size_helper(expected, func, args...) do { \
664617f55e2SKees Cook size_t _r = func(args); \
665617f55e2SKees Cook KUNIT_EXPECT_EQ_MSG(test, _r, expected, \
666617f55e2SKees Cook "expected " #func "(" #args ") to return %zu but got %zu instead\n", \
667617f55e2SKees Cook (size_t)(expected), _r); \
668617f55e2SKees Cook count++; \
669617f55e2SKees Cook } while (0)
670617f55e2SKees Cook
671617f55e2SKees Cook var = 4;
672617f55e2SKees Cook check_one_size_helper(20, size_mul, var++, 5);
673617f55e2SKees Cook check_one_size_helper(20, size_mul, 4, var++);
674617f55e2SKees Cook check_one_size_helper(0, size_mul, 0, 3);
675617f55e2SKees Cook check_one_size_helper(0, size_mul, 3, 0);
676617f55e2SKees Cook check_one_size_helper(6, size_mul, 2, 3);
677617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, 1);
678617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, 3);
679617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_mul, SIZE_MAX, -3);
680617f55e2SKees Cook
681617f55e2SKees Cook var = 4;
682617f55e2SKees Cook check_one_size_helper(9, size_add, var++, 5);
683617f55e2SKees Cook check_one_size_helper(9, size_add, 4, var++);
684617f55e2SKees Cook check_one_size_helper(9, size_add, 9, 0);
685617f55e2SKees Cook check_one_size_helper(9, size_add, 0, 9);
686617f55e2SKees Cook check_one_size_helper(5, size_add, 2, 3);
687617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, 1);
688617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, 3);
689617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, -3);
690617f55e2SKees Cook
691617f55e2SKees Cook var = 4;
692617f55e2SKees Cook check_one_size_helper(1, size_sub, var--, 3);
693617f55e2SKees Cook check_one_size_helper(1, size_sub, 4, var--);
694617f55e2SKees Cook check_one_size_helper(1, size_sub, 3, 2);
695617f55e2SKees Cook check_one_size_helper(9, size_sub, 9, 0);
696617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_sub, 9, -3);
697617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_sub, 0, 9);
698617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_sub, 2, 3);
699617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX, 0);
700617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX, 10);
701617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_sub, 0, SIZE_MAX);
702617f55e2SKees Cook check_one_size_helper(SIZE_MAX, size_sub, 14, SIZE_MAX);
703617f55e2SKees Cook check_one_size_helper(SIZE_MAX - 2, size_sub, SIZE_MAX - 1, 1);
704617f55e2SKees Cook check_one_size_helper(SIZE_MAX - 4, size_sub, SIZE_MAX - 1, 3);
705617f55e2SKees Cook check_one_size_helper(1, size_sub, SIZE_MAX - 1, -3);
706617f55e2SKees Cook
707617f55e2SKees Cook var = 4;
708617f55e2SKees Cook check_one_size_helper(4 * sizeof(*obj->data),
709617f55e2SKees Cook flex_array_size, obj, data, var++);
710617f55e2SKees Cook check_one_size_helper(5 * sizeof(*obj->data),
711617f55e2SKees Cook flex_array_size, obj, data, var++);
712617f55e2SKees Cook check_one_size_helper(0, flex_array_size, obj, data, 0 + unconst);
713617f55e2SKees Cook check_one_size_helper(sizeof(*obj->data),
714617f55e2SKees Cook flex_array_size, obj, data, 1 + unconst);
715617f55e2SKees Cook check_one_size_helper(7 * sizeof(*obj->data),
716617f55e2SKees Cook flex_array_size, obj, data, 7 + unconst);
717617f55e2SKees Cook check_one_size_helper(SIZE_MAX,
718617f55e2SKees Cook flex_array_size, obj, data, -1 + unconst);
719617f55e2SKees Cook check_one_size_helper(SIZE_MAX,
720617f55e2SKees Cook flex_array_size, obj, data, SIZE_MAX - 4 + unconst);
721617f55e2SKees Cook
722617f55e2SKees Cook var = 4;
723617f55e2SKees Cook check_one_size_helper(sizeof(*obj) + (4 * sizeof(*obj->data)),
724617f55e2SKees Cook struct_size, obj, data, var++);
725617f55e2SKees Cook check_one_size_helper(sizeof(*obj) + (5 * sizeof(*obj->data)),
726617f55e2SKees Cook struct_size, obj, data, var++);
727617f55e2SKees Cook check_one_size_helper(sizeof(*obj), struct_size, obj, data, 0 + unconst);
728617f55e2SKees Cook check_one_size_helper(sizeof(*obj) + sizeof(*obj->data),
729617f55e2SKees Cook struct_size, obj, data, 1 + unconst);
730617f55e2SKees Cook check_one_size_helper(SIZE_MAX,
731617f55e2SKees Cook struct_size, obj, data, -3 + unconst);
732617f55e2SKees Cook check_one_size_helper(SIZE_MAX,
733617f55e2SKees Cook struct_size, obj, data, SIZE_MAX - 3 + unconst);
734617f55e2SKees Cook
735617f55e2SKees Cook kunit_info(test, "%d overflow size helper tests finished\n", count);
736617f55e2SKees Cook #undef check_one_size_helper
737617f55e2SKees Cook }
738617f55e2SKees Cook
overflows_type_test(struct kunit * test)7394b21d25bSKees Cook static void overflows_type_test(struct kunit *test)
7404b21d25bSKees Cook {
7414b21d25bSKees Cook int count = 0;
7424b21d25bSKees Cook unsigned int var;
7434b21d25bSKees Cook
7444b21d25bSKees Cook #define __TEST_OVERFLOWS_TYPE(func, arg1, arg2, of) do { \
7454b21d25bSKees Cook bool __of = func(arg1, arg2); \
7464b21d25bSKees Cook KUNIT_EXPECT_EQ_MSG(test, __of, of, \
7474b21d25bSKees Cook "expected " #func "(" #arg1 ", " #arg2 " to%s overflow\n",\
7484b21d25bSKees Cook of ? "" : " not"); \
7494b21d25bSKees Cook count++; \
7504b21d25bSKees Cook } while (0)
7514b21d25bSKees Cook
7524b21d25bSKees Cook /* Args are: first type, second type, value, overflow expected */
7534b21d25bSKees Cook #define TEST_OVERFLOWS_TYPE(__t1, __t2, v, of) do { \
7544b21d25bSKees Cook __t1 t1 = (v); \
7554b21d25bSKees Cook __t2 t2; \
7564b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(__overflows_type, t1, t2, of); \
7574b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(__overflows_type, t1, __t2, of); \
7584b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(__overflows_type_constexpr, t1, t2, of); \
7594b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(__overflows_type_constexpr, t1, __t2, of);\
7604b21d25bSKees Cook } while (0)
7614b21d25bSKees Cook
7624b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u8, u8, U8_MAX, false);
7634b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
7644b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u8, s8, U8_MAX, true);
7654b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u8, s8, S8_MAX, false);
7664b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u8, s8, (u8)S8_MAX + 1, true);
7674b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
7684b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
7694b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
7704b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
7714b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
7724b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
7734b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
7744b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u32, S8_MAX, false);
7754b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u32, -1, true);
7764b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u32, S8_MIN, true);
7774b21d25bSKees Cook #if BITS_PER_LONG == 64
7784b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u64, S8_MAX, false);
7794b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u64, -1, true);
7804b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, u64, S8_MIN, true);
7814b21d25bSKees Cook #endif
7824b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, s8, S8_MAX, false);
7834b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, s8, S8_MIN, false);
7844b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
7854b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
7864b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, u8, U8_MAX, false);
7874b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, u8, (u16)U8_MAX + 1, true);
7884b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, u8, U16_MAX, true);
7894b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, s8, S8_MAX, false);
7904b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, s8, (u16)S8_MAX + 1, true);
7914b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, s8, U16_MAX, true);
7924b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, s16, S16_MAX, false);
7934b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, s16, (u16)S16_MAX + 1, true);
7944b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, s16, U16_MAX, true);
7954b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
7964b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
7974b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u8, U8_MAX, false);
7984b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u8, (s16)U8_MAX + 1, true);
7994b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u8, -1, true);
8004b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u8, S16_MIN, true);
8014b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
8024b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
8034b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
8044b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u32, S16_MAX, false);
8054b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u32, -1, true);
8064b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u32, S16_MIN, true);
8074b21d25bSKees Cook #if BITS_PER_LONG == 64
8084b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u64, S16_MAX, false);
8094b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u64, -1, true);
8104b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, u64, S16_MIN, true);
8114b21d25bSKees Cook #endif
8124b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s8, S8_MAX, false);
8134b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s8, S8_MIN, false);
8144b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MAX + 1, true);
8154b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MIN - 1, true);
8164b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s8, S16_MAX, true);
8174b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s8, S16_MIN, true);
8184b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s16, S16_MAX, false);
8194b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s16, S16_MIN, false);
8204b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
8214b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
8224b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, u8, U8_MAX, false);
8234b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, u8, (u32)U8_MAX + 1, true);
8244b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, u8, U32_MAX, true);
8254b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s8, S8_MAX, false);
8264b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s8, (u32)S8_MAX + 1, true);
8274b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s8, U32_MAX, true);
8284b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX, false);
8294b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX + 1, true);
8304b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, u16, U32_MAX, true);
8314b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s16, S16_MAX, false);
8324b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s16, (u32)S16_MAX + 1, true);
8334b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s16, U32_MAX, true);
8344b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, u32, U32_MAX, false);
8354b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s32, S32_MAX, false);
8364b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s32, U32_MAX, true);
8374b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s32, (u32)S32_MAX + 1, true);
8384b21d25bSKees Cook #if BITS_PER_LONG == 64
8394b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
8404b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
8414b21d25bSKees Cook #endif
8424b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u8, U8_MAX, false);
8434b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u8, (s32)U8_MAX + 1, true);
8444b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
8454b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u8, -1, true);
8464b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u8, S32_MIN, true);
8474b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u16, U16_MAX, false);
8484b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u16, (s32)U16_MAX + 1, true);
8494b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
8504b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u16, -1, true);
8514b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u16, S32_MIN, true);
8524b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u32, S32_MAX, false);
8534b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u32, -1, true);
8544b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u32, S32_MIN, true);
8554b21d25bSKees Cook #if BITS_PER_LONG == 64
8564b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u64, S32_MAX, false);
8574b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u64, -1, true);
8584b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, u64, S32_MIN, true);
8594b21d25bSKees Cook #endif
8604b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s8, S8_MAX, false);
8614b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s8, S8_MIN, false);
8624b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MAX + 1, true);
8634b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MIN - 1, true);
8644b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s8, S32_MAX, true);
8654b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s8, S32_MIN, true);
8664b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s16, S16_MAX, false);
8674b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s16, S16_MIN, false);
8684b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MAX + 1, true);
8694b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MIN - 1, true);
8704b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s16, S32_MAX, true);
8714b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s16, S32_MIN, true);
8724b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s32, S32_MAX, false);
8734b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s32, S32_MIN, false);
8744b21d25bSKees Cook #if BITS_PER_LONG == 64
8754b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
8764b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
8774b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u8, U64_MAX, true);
8784b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u8, U8_MAX, false);
8794b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u8, (u64)U8_MAX + 1, true);
8804b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u16, U64_MAX, true);
8814b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u16, U16_MAX, false);
8824b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u16, (u64)U16_MAX + 1, true);
8834b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u32, U64_MAX, true);
8844b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u32, U32_MAX, false);
8854b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u32, (u64)U32_MAX + 1, true);
8864b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, u64, U64_MAX, false);
8874b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s8, S8_MAX, false);
8884b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s8, (u64)S8_MAX + 1, true);
8894b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s8, U64_MAX, true);
8904b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s16, S16_MAX, false);
8914b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s16, (u64)S16_MAX + 1, true);
8924b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s16, U64_MAX, true);
8934b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s32, S32_MAX, false);
8944b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s32, (u64)S32_MAX + 1, true);
8954b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s32, U64_MAX, true);
8964b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s64, S64_MAX, false);
8974b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s64, U64_MAX, true);
8984b21d25bSKees Cook TEST_OVERFLOWS_TYPE(u64, s64, (u64)S64_MAX + 1, true);
8994b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u8, S64_MAX, true);
9004b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u8, S64_MIN, true);
9014b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u8, -1, true);
9024b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u8, U8_MAX, false);
9034b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u8, (s64)U8_MAX + 1, true);
9044b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u16, S64_MAX, true);
9054b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u16, S64_MIN, true);
9064b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u16, -1, true);
9074b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u16, U16_MAX, false);
9084b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u16, (s64)U16_MAX + 1, true);
9094b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u32, S64_MAX, true);
9104b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u32, S64_MIN, true);
9114b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u32, -1, true);
9124b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u32, U32_MAX, false);
9134b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u32, (s64)U32_MAX + 1, true);
9144b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u64, S64_MAX, false);
9154b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u64, S64_MIN, true);
9164b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, u64, -1, true);
9174b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s8, S8_MAX, false);
9184b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s8, S8_MIN, false);
9194b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MAX + 1, true);
9204b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MIN - 1, true);
9214b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s8, S64_MAX, true);
9224b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s16, S16_MAX, false);
9234b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s16, S16_MIN, false);
9244b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MAX + 1, true);
9254b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MIN - 1, true);
9264b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s16, S64_MAX, true);
9274b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s32, S32_MAX, false);
9284b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s32, S32_MIN, false);
9294b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MAX + 1, true);
9304b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MIN - 1, true);
9314b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s32, S64_MAX, true);
9324b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s64, S64_MAX, false);
9334b21d25bSKees Cook TEST_OVERFLOWS_TYPE(s64, s64, S64_MIN, false);
9344b21d25bSKees Cook #endif
9354b21d25bSKees Cook
9364b21d25bSKees Cook /* Check for macro side-effects. */
9374b21d25bSKees Cook var = INT_MAX - 1;
9384b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, false);
9394b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, false);
9404b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, true);
9414b21d25bSKees Cook var = INT_MAX - 1;
9424b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(overflows_type, var++, int, false);
9434b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(overflows_type, var++, int, false);
9444b21d25bSKees Cook __TEST_OVERFLOWS_TYPE(overflows_type, var++, int, true);
9454b21d25bSKees Cook
9464b21d25bSKees Cook kunit_info(test, "%d overflows_type() tests finished\n", count);
9474b21d25bSKees Cook #undef TEST_OVERFLOWS_TYPE
9484b21d25bSKees Cook #undef __TEST_OVERFLOWS_TYPE
9494b21d25bSKees Cook }
9504b21d25bSKees Cook
same_type_test(struct kunit * test)9514b21d25bSKees Cook static void same_type_test(struct kunit *test)
9524b21d25bSKees Cook {
9534b21d25bSKees Cook int count = 0;
9544b21d25bSKees Cook int var;
9554b21d25bSKees Cook
9564b21d25bSKees Cook #define TEST_SAME_TYPE(t1, t2, same) do { \
9574b21d25bSKees Cook typeof(t1) __t1h = type_max(t1); \
9584b21d25bSKees Cook typeof(t1) __t1l = type_min(t1); \
9594b21d25bSKees Cook typeof(t2) __t2h = type_max(t2); \
9604b21d25bSKees Cook typeof(t2) __t2l = type_min(t2); \
9614b21d25bSKees Cook KUNIT_EXPECT_EQ(test, true, __same_type(t1, __t1h)); \
9624b21d25bSKees Cook KUNIT_EXPECT_EQ(test, true, __same_type(t1, __t1l)); \
9634b21d25bSKees Cook KUNIT_EXPECT_EQ(test, true, __same_type(__t1h, t1)); \
9644b21d25bSKees Cook KUNIT_EXPECT_EQ(test, true, __same_type(__t1l, t1)); \
9654b21d25bSKees Cook KUNIT_EXPECT_EQ(test, true, __same_type(t2, __t2h)); \
9664b21d25bSKees Cook KUNIT_EXPECT_EQ(test, true, __same_type(t2, __t2l)); \
9674b21d25bSKees Cook KUNIT_EXPECT_EQ(test, true, __same_type(__t2h, t2)); \
9684b21d25bSKees Cook KUNIT_EXPECT_EQ(test, true, __same_type(__t2l, t2)); \
9694b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(t1, t2)); \
9704b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(t2, __t1h)); \
9714b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(t2, __t1l)); \
9724b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(__t1h, t2)); \
9734b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(__t1l, t2)); \
9744b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(t1, __t2h)); \
9754b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(t1, __t2l)); \
9764b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(__t2h, t1)); \
9774b21d25bSKees Cook KUNIT_EXPECT_EQ(test, same, __same_type(__t2l, t1)); \
9784b21d25bSKees Cook } while (0)
9794b21d25bSKees Cook
9804b21d25bSKees Cook #if BITS_PER_LONG == 64
9814b21d25bSKees Cook # define TEST_SAME_TYPE64(base, t, m) TEST_SAME_TYPE(base, t, m)
9824b21d25bSKees Cook #else
9834b21d25bSKees Cook # define TEST_SAME_TYPE64(base, t, m) do { } while (0)
9844b21d25bSKees Cook #endif
9854b21d25bSKees Cook
9864b21d25bSKees Cook #define TEST_TYPE_SETS(base, mu8, mu16, mu32, ms8, ms16, ms32, mu64, ms64) \
9874b21d25bSKees Cook do { \
9884b21d25bSKees Cook TEST_SAME_TYPE(base, u8, mu8); \
9894b21d25bSKees Cook TEST_SAME_TYPE(base, u16, mu16); \
9904b21d25bSKees Cook TEST_SAME_TYPE(base, u32, mu32); \
9914b21d25bSKees Cook TEST_SAME_TYPE(base, s8, ms8); \
9924b21d25bSKees Cook TEST_SAME_TYPE(base, s16, ms16); \
9934b21d25bSKees Cook TEST_SAME_TYPE(base, s32, ms32); \
9944b21d25bSKees Cook TEST_SAME_TYPE64(base, u64, mu64); \
9954b21d25bSKees Cook TEST_SAME_TYPE64(base, s64, ms64); \
9964b21d25bSKees Cook } while (0)
9974b21d25bSKees Cook
9984b21d25bSKees Cook TEST_TYPE_SETS(u8, true, false, false, false, false, false, false, false);
9994b21d25bSKees Cook TEST_TYPE_SETS(u16, false, true, false, false, false, false, false, false);
10004b21d25bSKees Cook TEST_TYPE_SETS(u32, false, false, true, false, false, false, false, false);
10014b21d25bSKees Cook TEST_TYPE_SETS(s8, false, false, false, true, false, false, false, false);
10024b21d25bSKees Cook TEST_TYPE_SETS(s16, false, false, false, false, true, false, false, false);
10034b21d25bSKees Cook TEST_TYPE_SETS(s32, false, false, false, false, false, true, false, false);
10044b21d25bSKees Cook #if BITS_PER_LONG == 64
10054b21d25bSKees Cook TEST_TYPE_SETS(u64, false, false, false, false, false, false, true, false);
10064b21d25bSKees Cook TEST_TYPE_SETS(s64, false, false, false, false, false, false, false, true);
10074b21d25bSKees Cook #endif
10084b21d25bSKees Cook
10094b21d25bSKees Cook /* Check for macro side-effects. */
10104b21d25bSKees Cook var = 4;
10114b21d25bSKees Cook KUNIT_EXPECT_EQ(test, var, 4);
10124b21d25bSKees Cook KUNIT_EXPECT_TRUE(test, __same_type(var++, int));
10134b21d25bSKees Cook KUNIT_EXPECT_EQ(test, var, 4);
10144b21d25bSKees Cook KUNIT_EXPECT_TRUE(test, __same_type(int, var++));
10154b21d25bSKees Cook KUNIT_EXPECT_EQ(test, var, 4);
10164b21d25bSKees Cook KUNIT_EXPECT_TRUE(test, __same_type(var++, var++));
10174b21d25bSKees Cook KUNIT_EXPECT_EQ(test, var, 4);
10184b21d25bSKees Cook
10194b21d25bSKees Cook kunit_info(test, "%d __same_type() tests finished\n", count);
10204b21d25bSKees Cook
10214b21d25bSKees Cook #undef TEST_TYPE_SETS
10224b21d25bSKees Cook #undef TEST_SAME_TYPE64
10234b21d25bSKees Cook #undef TEST_SAME_TYPE
10244b21d25bSKees Cook }
10254b21d25bSKees Cook
castable_to_type_test(struct kunit * test)10264b21d25bSKees Cook static void castable_to_type_test(struct kunit *test)
10274b21d25bSKees Cook {
10284b21d25bSKees Cook int count = 0;
10294b21d25bSKees Cook
10304b21d25bSKees Cook #define TEST_CASTABLE_TO_TYPE(arg1, arg2, pass) do { \
10314b21d25bSKees Cook bool __pass = castable_to_type(arg1, arg2); \
10324b21d25bSKees Cook KUNIT_EXPECT_EQ_MSG(test, __pass, pass, \
10334b21d25bSKees Cook "expected castable_to_type(" #arg1 ", " #arg2 ") to%s pass\n",\
10344b21d25bSKees Cook pass ? "" : " not"); \
10354b21d25bSKees Cook count++; \
10364b21d25bSKees Cook } while (0)
10374b21d25bSKees Cook
10384b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(16, u8, true);
10394b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(16, u16, true);
10404b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(16, u32, true);
10414b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(16, s8, true);
10424b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(16, s16, true);
10434b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(16, s32, true);
10444b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(-16, s8, true);
10454b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(-16, s16, true);
10464b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(-16, s32, true);
10474b21d25bSKees Cook #if BITS_PER_LONG == 64
10484b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(16, u64, true);
10494b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(-16, s64, true);
10504b21d25bSKees Cook #endif
10514b21d25bSKees Cook
10524b21d25bSKees Cook #define TEST_CASTABLE_TO_TYPE_VAR(width) do { \
10534b21d25bSKees Cook u ## width u ## width ## var = 0; \
10544b21d25bSKees Cook s ## width s ## width ## var = 0; \
10554b21d25bSKees Cook \
10564b21d25bSKees Cook /* Constant expressions that fit types. */ \
10574b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_max(u ## width), u ## width, true); \
10584b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_min(u ## width), u ## width, true); \
10594b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_max(u ## width), u ## width ## var, true); \
10604b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_min(u ## width), u ## width ## var, true); \
10614b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_max(s ## width), s ## width, true); \
10624b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_min(s ## width), s ## width, true); \
10634b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_max(s ## width), s ## width ## var, true); \
10644b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_min(u ## width), s ## width ## var, true); \
10654b21d25bSKees Cook /* Constant expressions that do not fit types. */ \
10664b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_max(u ## width), s ## width, false); \
10674b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_max(u ## width), s ## width ## var, false); \
10684b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_min(s ## width), u ## width, false); \
10694b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(type_min(s ## width), u ## width ## var, false); \
10704b21d25bSKees Cook /* Non-constant expression with mismatched type. */ \
10714b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(s ## width ## var, u ## width, false); \
10724b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(u ## width ## var, s ## width, false); \
10734b21d25bSKees Cook } while (0)
10744b21d25bSKees Cook
10754b21d25bSKees Cook #define TEST_CASTABLE_TO_TYPE_RANGE(width) do { \
10764b21d25bSKees Cook unsigned long big = U ## width ## _MAX; \
10774b21d25bSKees Cook signed long small = S ## width ## _MIN; \
10784b21d25bSKees Cook u ## width u ## width ## var = 0; \
10794b21d25bSKees Cook s ## width s ## width ## var = 0; \
10804b21d25bSKees Cook \
10814b21d25bSKees Cook /* Constant expression in range. */ \
10824b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(U ## width ## _MAX, u ## width, true); \
10834b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(U ## width ## _MAX, u ## width ## var, true); \
10844b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(S ## width ## _MIN, s ## width, true); \
10854b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(S ## width ## _MIN, s ## width ## var, true); \
10864b21d25bSKees Cook /* Constant expression out of range. */ \
10874b21d25bSKees Cook TEST_CASTABLE_TO_TYPE((unsigned long)U ## width ## _MAX + 1, u ## width, false); \
10884b21d25bSKees Cook TEST_CASTABLE_TO_TYPE((unsigned long)U ## width ## _MAX + 1, u ## width ## var, false); \
10894b21d25bSKees Cook TEST_CASTABLE_TO_TYPE((signed long)S ## width ## _MIN - 1, s ## width, false); \
10904b21d25bSKees Cook TEST_CASTABLE_TO_TYPE((signed long)S ## width ## _MIN - 1, s ## width ## var, false); \
10914b21d25bSKees Cook /* Non-constant expression with mismatched type. */ \
10924b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(big, u ## width, false); \
10934b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(big, u ## width ## var, false); \
10944b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(small, s ## width, false); \
10954b21d25bSKees Cook TEST_CASTABLE_TO_TYPE(small, s ## width ## var, false); \
10964b21d25bSKees Cook } while (0)
10974b21d25bSKees Cook
10984b21d25bSKees Cook TEST_CASTABLE_TO_TYPE_VAR(8);
10994b21d25bSKees Cook TEST_CASTABLE_TO_TYPE_VAR(16);
11004b21d25bSKees Cook TEST_CASTABLE_TO_TYPE_VAR(32);
11014b21d25bSKees Cook #if BITS_PER_LONG == 64
11024b21d25bSKees Cook TEST_CASTABLE_TO_TYPE_VAR(64);
11034b21d25bSKees Cook #endif
11044b21d25bSKees Cook
11054b21d25bSKees Cook TEST_CASTABLE_TO_TYPE_RANGE(8);
11064b21d25bSKees Cook TEST_CASTABLE_TO_TYPE_RANGE(16);
11074b21d25bSKees Cook #if BITS_PER_LONG == 64
11084b21d25bSKees Cook TEST_CASTABLE_TO_TYPE_RANGE(32);
11094b21d25bSKees Cook #endif
11104b21d25bSKees Cook kunit_info(test, "%d castable_to_type() tests finished\n", count);
11114b21d25bSKees Cook
11124b21d25bSKees Cook #undef TEST_CASTABLE_TO_TYPE_RANGE
11134b21d25bSKees Cook #undef TEST_CASTABLE_TO_TYPE_VAR
11144b21d25bSKees Cook #undef TEST_CASTABLE_TO_TYPE
11154b21d25bSKees Cook }
11164b21d25bSKees Cook
1117617f55e2SKees Cook static struct kunit_case overflow_test_cases[] = {
1118d219d2a9SKees Cook KUNIT_CASE(u8_u8__u8_overflow_test),
1119d219d2a9SKees Cook KUNIT_CASE(s8_s8__s8_overflow_test),
1120d219d2a9SKees Cook KUNIT_CASE(u16_u16__u16_overflow_test),
1121d219d2a9SKees Cook KUNIT_CASE(s16_s16__s16_overflow_test),
1122d219d2a9SKees Cook KUNIT_CASE(u32_u32__u32_overflow_test),
1123d219d2a9SKees Cook KUNIT_CASE(s32_s32__s32_overflow_test),
1124d219d2a9SKees Cook KUNIT_CASE(u64_u64__u64_overflow_test),
1125d219d2a9SKees Cook KUNIT_CASE(s64_s64__s64_overflow_test),
1126d219d2a9SKees Cook KUNIT_CASE(u32_u32__int_overflow_test),
11270e5b9f25SNick Desaulniers KUNIT_CASE(u32_u32__u8_overflow_test),
1128d219d2a9SKees Cook KUNIT_CASE(u8_u8__int_overflow_test),
1129d219d2a9SKees Cook KUNIT_CASE(int_int__u8_overflow_test),
113077974225SKees Cook KUNIT_CASE(shift_sane_test),
113177974225SKees Cook KUNIT_CASE(shift_overflow_test),
113277974225SKees Cook KUNIT_CASE(shift_truncate_test),
113377974225SKees Cook KUNIT_CASE(shift_nonsense_test),
1134617f55e2SKees Cook KUNIT_CASE(overflow_allocation_test),
1135617f55e2SKees Cook KUNIT_CASE(overflow_size_helpers_test),
11364b21d25bSKees Cook KUNIT_CASE(overflows_type_test),
11374b21d25bSKees Cook KUNIT_CASE(same_type_test),
11384b21d25bSKees Cook KUNIT_CASE(castable_to_type_test),
1139617f55e2SKees Cook {}
1140617f55e2SKees Cook };
1141617f55e2SKees Cook
1142617f55e2SKees Cook static struct kunit_suite overflow_test_suite = {
1143617f55e2SKees Cook .name = "overflow",
1144617f55e2SKees Cook .test_cases = overflow_test_cases,
1145617f55e2SKees Cook };
1146617f55e2SKees Cook
1147617f55e2SKees Cook kunit_test_suite(overflow_test_suite);
1148617f55e2SKees Cook
1149617f55e2SKees Cook MODULE_LICENSE("Dual MIT/GPL");
1150