// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
* Test cases for arithmetic overflow checks. See:
* "Running tests with kunit_tool" at Documentation/dev-tools/kunit/start.rst
* ./tools/testing/kunit/kunit.py run overflow [--raw_output]
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <kunit/test.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#define SKIP(cond, reason) do { \
if (cond) { \
kunit_skip(test, reason); \
return; \
} \
} while (0)
/*
* Clang 11 and earlier generate unwanted libcalls for signed output
* on unsigned input.
*/
#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 11
# define SKIP_SIGN_MISMATCH(t) SKIP(t, "Clang 11 unwanted libcalls")
#else
# define SKIP_SIGN_MISMATCH(t) do { } while (0)
#endif
/*
* Clang 13 and earlier generate unwanted libcalls for 64-bit tests on
* 32-bit hosts.
*/
#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 13 && \
BITS_PER_LONG != 64
# define SKIP_64_ON_32(t) SKIP(t, "Clang 13 unwanted libcalls")
#else
# define SKIP_64_ON_32(t) do { } while (0)
#endif
#define DEFINE_TEST_ARRAY_TYPED(t1, t2, t) \
static const struct test_ ## t1 ## _ ## t2 ## __ ## t { \
t1 a; \
t2 b; \
t sum, diff, prod; \
bool s_of, d_of, p_of; \
} t1 ## _ ## t2 ## __ ## t ## _tests[]
#define DEFINE_TEST_ARRAY(t) DEFINE_TEST_ARRAY_TYPED(t, t, t)
DEFINE_TEST_ARRAY(u8) = {
{0, 0, 0, 0, 0, false, false, false},
{1, 1, 2, 0, 1, false, false, false},
{0, 1, 1, U8_MAX, 0, false, true, false},
{1, 0, 1, 1, 0, false, false, false},
{0, U8_MAX, U8_MAX, 1, 0, false, true, false},
{U8_MAX, 0, U8_MAX, U8_MAX, 0, false, false, false},
{1, U8_MAX, 0, 2, U8_MAX, true, true, false},
{U8_MAX, 1, 0, U8_MAX-1, U8_MAX, true, false, false},
{U8_MAX, U8_MAX, U8_MAX-1, 0, 1, true, false, true},
{U8_MAX, U8_MAX-1, U8_MAX-2, 1, 2, true, false, true},
{U8_MAX-1, U8_MAX, U8_MAX-2, U8_MAX, 2, true, true, true},
{1U << 3, 1U << 3, 1U << 4, 0, 1U << 6, false, false, false},
{1U << 4, 1U << 4, 1U << 5, 0, 0, false, false, true},
{1U << 4, 1U << 3, 3*(1U << 3), 1U << 3, 1U << 7, false, false, false},
{1U << 7, 1U << 7, 0, 0, 0, true, false, true},
{48, 32, 80, 16, 0, false, false, true},
{128, 128, 0, 0, 0, true, false, true},
{123, 234, 101, 145, 110, true, true, true},
};
DEFINE_TEST_ARRAY(u16) = {
{0, 0, 0, 0, 0, false, false, false},
{1, 1, 2, 0, 1, false, false, false},
{0, 1, 1, U16_MAX, 0, false, true, false},
{1, 0, 1, 1, 0, false, false, false},
{0, U16_MAX, U16_MAX, 1, 0, false, true, false},
{U16_MAX, 0, U16_MAX, U16_MAX, 0, false, false, false},
{1, U16_MAX, 0, 2, U16_MAX, true, true, false},
{U16_MAX, 1, 0, U16_MAX-1, U16_MAX, true, false, false},
{U16_MAX, U16_MAX, U16_MAX-1, 0, 1, true, false,