diff mbox series

[v11,3/9] compiler_types.h: Add assert_same_type to catch type mis-match while compiling

Message ID 20220923082628.3061408-4-gwan-gyeong.mun@intel.com (mailing list archive)
State New, archived
Headers show
Series Fixes integer overflow or integer truncation issues in page lookups, ttm place configuration and scatterlist creation | expand

Commit Message

Gwan-gyeong Mun Sept. 23, 2022, 8:26 a.m. UTC
Adds assert_same_type and assert_same_typable macros to catch type
mis-match while compiling. The existing typecheck() macro outputs build
warnings, but the newly added assert_same_type() macro uses the
static_assert macro (which uses _Static_assert keyword and it introduced
in C11) to generate a build break when the types are different and can be
used to detect explicit build errors. Unlike the assert_same_type() macro,
assert_same_typable() macro allows a constant value as the second argument.
Since static_assert is used at compile time and it requires
constant-expression as an argument [1][2], overflows_type_ret_const_expr()
is newly added. There is overflows_type() that has the same behavior, but
the macro uses __builtin_add_overflow() internally, and
__builtin_add_overflows returns a bool type [3], so it is difficult to use
as an argument of _Static_assert. The assert_same_type and
assert_same_typable macros have been added to compiler_types.h, but the
overflows_type_ret_const_expr macro has been added to overflow.h
So, overflow.h has to be included to use assert_same_typable which
internally uses overflows_type_ret_const_expr.
And it adds unit tests for overflows_type, overflows_type_ret_const_expr,
assert_same_type and assert_same_typable. The overflows_type has been added
as well to compare whether the overflows_type_ret_const_expr unit test has
the same as the result.

[1] https://en.cppreference.com/w/c/language/_Static_assert
[2] C11 standard (ISO/IEC 9899:2011): 6.7.10 Static assertions
[3] https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
    6.56 Built-in Functions to Perform Arithmetic with Overflow Checking
    Built-in Function: bool __builtin_add_overflow (type1 a, type2 b,
                                                    type3 *res)

v11: Update macro description (Andi)
     Change _Static_assert to static_assert (Rasmus)
     Rename assert_type to assert_same_type and  assert_typable to
     assert_same_typable (Rasmus)
     Update assert_same_typable macro to handle an overflow check on the
     target type when a constant value is used. (Kees)
     Add overflows_type_ret_const_expr which returns constant-expression
     value (G.G)
     Add is_unsigned_type (G.G)
     Add unit tests for overflows_type, overflows_type_ret_const_expr,
     assert_same_type and assert_same_typable. (Kees)

Suggested-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Nirmoy Das <nirmoy.das@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Andi Shyti <andi.shyti@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 include/linux/compiler.h       |   1 +
 include/linux/compiler_types.h |  43 +++++
 include/linux/overflow.h       |  27 ++++
 lib/overflow_kunit.c           | 283 +++++++++++++++++++++++++++++++++
 4 files changed, 354 insertions(+)

Comments

kernel test robot Sept. 24, 2022, 4:21 a.m. UTC | #1
Hi Gwan-gyeong,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]

url:    https://github.com/intel-lab-lkp/linux/commits/Gwan-gyeong-Mun/Fixes-integer-overflow-or-integer-truncation-issues-in-page-lookups-ttm-place-configuration-and-scatterlist-creation/20220923-163015
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: hexagon-randconfig-r041-20220923
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 791a7ae1ba3efd6bca96338e10ffde557ba83920)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/90f09a98b3949d759efe6febd174ed6e26c1a3ab
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Gwan-gyeong-Mun/Fixes-integer-overflow-or-integer-truncation-issues-in-page-lookups-ttm-place-configuration-and-scatterlist-creation/20220923-163015
        git checkout 90f09a98b3949d759efe6febd174ed6e26c1a3ab
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash lib/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> lib/overflow_kunit.c:748:2: warning: result of comparison of constant 65535 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:748:2: warning: result of comparison of constant 65535 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:752:2: warning: result of comparison of constant 32767 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:752:2: warning: result of comparison of constant 32767 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:753:2: warning: result of comparison of constant 255 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:753:2: warning: result of comparison of constant 255 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:754:2: warning: result of comparison of constant 255 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:754:2: warning: result of comparison of constant 255 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:755:2: warning: result of comparison of constant 255 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:755:2: warning: result of comparison of constant 255 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:756:2: warning: result of comparison of constant 65535 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:756:2: warning: result of comparison of constant 65535 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:757:2: warning: result of comparison of constant 65535 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:757:2: warning: result of comparison of constant 65535 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:758:2: warning: result of comparison of constant 65535 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:758:2: warning: result of comparison of constant 65535 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:769:2: warning: result of comparison of constant 32767 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:769:2: warning: result of comparison of constant -32768 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:769:2: warning: result of comparison of constant 32767 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:769:2: warning: result of comparison of constant -32768 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:770:2: warning: result of comparison of constant 32767 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:770:2: warning: result of comparison of constant -32768 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:770:2: warning: result of comparison of constant 32767 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:770:2: warning: result of comparison of constant -32768 with expression of type 's8' (aka 'signed char') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:780:2: warning: result of comparison of constant 4294967295 with expression of type 'u16' (aka 'unsigned short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:780:2: warning: result of comparison of constant 4294967295 with expression of type 'u16' (aka 'unsigned short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:781:2: warning: result of comparison of constant 2147483647 with expression of type 'u16' (aka 'unsigned short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:781:2: warning: result of comparison of constant 2147483647 with expression of type 'u16' (aka 'unsigned short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:786:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:786:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:787:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:787:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:788:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:788:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:805:2: warning: result of comparison of constant 2147483647 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:805:2: warning: result of comparison of constant -2147483648 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:805:2: warning: result of comparison of constant 2147483647 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:805:2: warning: result of comparison of constant -2147483648 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:806:2: warning: result of comparison of constant 2147483647 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:806:2: warning: result of comparison of constant -2147483648 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:806:2: warning: result of comparison of constant 2147483647 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);


vim +748 lib/overflow_kunit.c

   746	
   747		TEST_OVERFLOWS_TYPE(u8, u8, U8_MAX, false);
 > 748		TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
   749		TEST_OVERFLOWS_TYPE(u8, s8, U8_MAX, true);
   750		TEST_OVERFLOWS_TYPE(u8, s8, S8_MAX, false);
   751		TEST_OVERFLOWS_TYPE(u8, s8, (u8)S8_MAX + 1, true);
   752		TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
 > 753		TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
   754		TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
   755		TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
   756		TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
   757		TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
   758		TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
   759		TEST_OVERFLOWS_TYPE(s8, u32, S8_MAX, false);
   760		TEST_OVERFLOWS_TYPE(s8, u32, -1, true);
   761		TEST_OVERFLOWS_TYPE(s8, u32, S8_MIN, true);
   762	#if BITS_PER_LONG == 64
   763		TEST_OVERFLOWS_TYPE(s8, u64, S8_MAX, false);
   764		TEST_OVERFLOWS_TYPE(s8, u64, -1, true);
   765		TEST_OVERFLOWS_TYPE(s8, u64, S8_MIN, true);
   766	#endif
   767		TEST_OVERFLOWS_TYPE(s8, s8, S8_MAX, false);
   768		TEST_OVERFLOWS_TYPE(s8, s8, S8_MIN, false);
   769		TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
   770		TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
   771		TEST_OVERFLOWS_TYPE(u16, u8, U8_MAX, false);
   772		TEST_OVERFLOWS_TYPE(u16, u8, (u16)U8_MAX + 1, true);
   773		TEST_OVERFLOWS_TYPE(u16, u8, U16_MAX, true);
   774		TEST_OVERFLOWS_TYPE(u16, s8, S8_MAX, false);
   775		TEST_OVERFLOWS_TYPE(u16, s8, (u16)S8_MAX + 1, true);
   776		TEST_OVERFLOWS_TYPE(u16, s8, U16_MAX, true);
   777		TEST_OVERFLOWS_TYPE(u16, s16, S16_MAX, false);
   778		TEST_OVERFLOWS_TYPE(u16, s16, (u16)S16_MAX + 1, true);
   779		TEST_OVERFLOWS_TYPE(u16, s16, U16_MAX, true);
 > 780		TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
   781		TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
   782		TEST_OVERFLOWS_TYPE(s16, u8, U8_MAX, false);
   783		TEST_OVERFLOWS_TYPE(s16, u8, (s16)U8_MAX + 1, true);
   784		TEST_OVERFLOWS_TYPE(s16, u8, -1, true);
   785		TEST_OVERFLOWS_TYPE(s16, u8, S16_MIN, true);
 > 786		TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
   787		TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
   788		TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
   789		TEST_OVERFLOWS_TYPE(s16, u32, S16_MAX, false);
   790		TEST_OVERFLOWS_TYPE(s16, u32, -1, true);
   791		TEST_OVERFLOWS_TYPE(s16, u32, S16_MIN, true);
   792	#if BITS_PER_LONG == 64
   793		TEST_OVERFLOWS_TYPE(s16, u64, S16_MAX, false);
   794		TEST_OVERFLOWS_TYPE(s16, u64, -1, true);
   795		TEST_OVERFLOWS_TYPE(s16, u64, S16_MIN, true);
   796	#endif
   797		TEST_OVERFLOWS_TYPE(s16, s8, S8_MAX, false);
   798		TEST_OVERFLOWS_TYPE(s16, s8, S8_MIN, false);
   799		TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MAX + 1, true);
   800		TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MIN - 1, true);
   801		TEST_OVERFLOWS_TYPE(s16, s8, S16_MAX, true);
   802		TEST_OVERFLOWS_TYPE(s16, s8, S16_MIN, true);
   803		TEST_OVERFLOWS_TYPE(s16, s16, S16_MAX, false);
   804		TEST_OVERFLOWS_TYPE(s16, s16, S16_MIN, false);
   805		TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
   806		TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
   807		TEST_OVERFLOWS_TYPE(u32, u8, U8_MAX, false);
   808		TEST_OVERFLOWS_TYPE(u32, u8, (u32)U8_MAX + 1, true);
   809		TEST_OVERFLOWS_TYPE(u32, u8, U32_MAX, true);
   810		TEST_OVERFLOWS_TYPE(u32, s8, S8_MAX, false);
   811		TEST_OVERFLOWS_TYPE(u32, s8, (u32)S8_MAX + 1, true);
   812		TEST_OVERFLOWS_TYPE(u32, s8, U32_MAX, true);
   813		TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX, false);
   814		TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX + 1, true);
   815		TEST_OVERFLOWS_TYPE(u32, u16, U32_MAX, true);
   816		TEST_OVERFLOWS_TYPE(u32, s16, S16_MAX, false);
   817		TEST_OVERFLOWS_TYPE(u32, s16, (u32)S16_MAX + 1, true);
   818		TEST_OVERFLOWS_TYPE(u32, s16, U32_MAX, true);
   819		TEST_OVERFLOWS_TYPE(u32, u32, U32_MAX, false);
   820		TEST_OVERFLOWS_TYPE(u32, s32, S32_MAX, false);
   821		TEST_OVERFLOWS_TYPE(u32, s32, U32_MAX, true);
   822		TEST_OVERFLOWS_TYPE(u32, s32, (u32)S32_MAX + 1, true);
   823	#if BITS_PER_LONG == 64
   824		TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
   825		TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
   826	#endif
   827		TEST_OVERFLOWS_TYPE(s32, u8, U8_MAX, false);
   828		TEST_OVERFLOWS_TYPE(s32, u8, (s32)U8_MAX + 1, true);
   829		TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
   830		TEST_OVERFLOWS_TYPE(s32, u8, -1, true);
   831		TEST_OVERFLOWS_TYPE(s32, u8, S32_MIN, true);
   832		TEST_OVERFLOWS_TYPE(s32, u16, U16_MAX, false);
   833		TEST_OVERFLOWS_TYPE(s32, u16, (s32)U16_MAX + 1, true);
   834		TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
   835		TEST_OVERFLOWS_TYPE(s32, u16, -1, true);
   836		TEST_OVERFLOWS_TYPE(s32, u16, S32_MIN, true);
   837		TEST_OVERFLOWS_TYPE(s32, u32, S32_MAX, false);
   838		TEST_OVERFLOWS_TYPE(s32, u32, -1, true);
   839		TEST_OVERFLOWS_TYPE(s32, u32, S32_MIN, true);
   840	#if BITS_PER_LONG == 64
   841		TEST_OVERFLOWS_TYPE(s32, u64, S32_MAX, false);
   842		TEST_OVERFLOWS_TYPE(s32, u64, -1, true);
   843		TEST_OVERFLOWS_TYPE(s32, u64, S32_MIN, true);
   844	#endif
   845		TEST_OVERFLOWS_TYPE(s32, s8, S8_MAX, false);
   846		TEST_OVERFLOWS_TYPE(s32, s8, S8_MIN, false);
   847		TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MAX + 1, true);
   848		TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MIN - 1, true);
   849		TEST_OVERFLOWS_TYPE(s32, s8, S32_MAX, true);
   850		TEST_OVERFLOWS_TYPE(s32, s8, S32_MIN, true);
   851		TEST_OVERFLOWS_TYPE(s32, s16, S16_MAX, false);
   852		TEST_OVERFLOWS_TYPE(s32, s16, S16_MIN, false);
   853		TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MAX + 1, true);
   854		TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MIN - 1, true);
   855		TEST_OVERFLOWS_TYPE(s32, s16, S32_MAX, true);
   856		TEST_OVERFLOWS_TYPE(s32, s16, S32_MIN, true);
   857		TEST_OVERFLOWS_TYPE(s32, s32, S32_MAX, false);
   858		TEST_OVERFLOWS_TYPE(s32, s32, S32_MIN, false);
   859	#if BITS_PER_LONG == 64
   860		TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
   861		TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
   862		TEST_OVERFLOWS_TYPE(u64, u8, U64_MAX, true);
   863		TEST_OVERFLOWS_TYPE(u64, u8, U8_MAX, false);
   864		TEST_OVERFLOWS_TYPE(u64, u8, (u64)U8_MAX + 1, true);
   865		TEST_OVERFLOWS_TYPE(u64, u16, U64_MAX, true);
   866		TEST_OVERFLOWS_TYPE(u64, u16, U16_MAX, false);
   867		TEST_OVERFLOWS_TYPE(u64, u16, (u64)U16_MAX + 1, true);
   868		TEST_OVERFLOWS_TYPE(u64, u32, U64_MAX, true);
   869		TEST_OVERFLOWS_TYPE(u64, u32, U32_MAX, false);
   870		TEST_OVERFLOWS_TYPE(u64, u32, (u64)U32_MAX + 1, true);
   871		TEST_OVERFLOWS_TYPE(u64, u64, U64_MAX, false);
   872		TEST_OVERFLOWS_TYPE(u64, s8, S8_MAX, false);
   873		TEST_OVERFLOWS_TYPE(u64, s8, (u64)S8_MAX + 1, true);
   874		TEST_OVERFLOWS_TYPE(u64, s8, U64_MAX, true);
   875		TEST_OVERFLOWS_TYPE(u64, s16, S16_MAX, false);
   876		TEST_OVERFLOWS_TYPE(u64, s16, (u64)S16_MAX + 1, true);
   877		TEST_OVERFLOWS_TYPE(u64, s16, U64_MAX, true);
   878		TEST_OVERFLOWS_TYPE(u64, s32, S32_MAX, false);
   879		TEST_OVERFLOWS_TYPE(u64, s32, (u64)S32_MAX + 1, true);
   880		TEST_OVERFLOWS_TYPE(u64, s32, U64_MAX, true);
   881		TEST_OVERFLOWS_TYPE(u64, s64, S64_MAX, false);
   882		TEST_OVERFLOWS_TYPE(u64, s64, U64_MAX, true);
   883		TEST_OVERFLOWS_TYPE(u64, s64, (u64)S64_MAX + 1, true);
   884		TEST_OVERFLOWS_TYPE(s64, u8, S64_MAX, true);
   885		TEST_OVERFLOWS_TYPE(s64, u8, S64_MIN, true);
   886		TEST_OVERFLOWS_TYPE(s64, u8, -1, true);
   887		TEST_OVERFLOWS_TYPE(s64, u8, U8_MAX, false);
   888		TEST_OVERFLOWS_TYPE(s64, u8, (s64)U8_MAX + 1, true);
   889		TEST_OVERFLOWS_TYPE(s64, u16, S64_MAX, true);
   890		TEST_OVERFLOWS_TYPE(s64, u16, S64_MIN, true);
   891		TEST_OVERFLOWS_TYPE(s64, u16, -1, true);
   892		TEST_OVERFLOWS_TYPE(s64, u16, U16_MAX, false);
   893		TEST_OVERFLOWS_TYPE(s64, u16, (s64)U16_MAX + 1, true);
   894		TEST_OVERFLOWS_TYPE(s64, u32, S64_MAX, true);
   895		TEST_OVERFLOWS_TYPE(s64, u32, S64_MIN, true);
   896		TEST_OVERFLOWS_TYPE(s64, u32, -1, true);
   897		TEST_OVERFLOWS_TYPE(s64, u32, U32_MAX, false);
   898		TEST_OVERFLOWS_TYPE(s64, u32, (s64)U32_MAX + 1, true);
   899		TEST_OVERFLOWS_TYPE(s64, u64, S64_MAX, false);
   900		TEST_OVERFLOWS_TYPE(s64, u64, S64_MIN, true);
   901		TEST_OVERFLOWS_TYPE(s64, u64, -1, true);
   902		TEST_OVERFLOWS_TYPE(s64, s8, S8_MAX, false);
   903		TEST_OVERFLOWS_TYPE(s64, s8, S8_MIN, false);
   904		TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MAX + 1, true);
   905		TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MIN - 1, true);
   906		TEST_OVERFLOWS_TYPE(s64, s8, S64_MAX, true);
   907		TEST_OVERFLOWS_TYPE(s64, s16, S16_MAX, false);
   908		TEST_OVERFLOWS_TYPE(s64, s16, S16_MIN, false);
   909		TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MAX + 1, true);
   910		TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MIN - 1, true);
   911		TEST_OVERFLOWS_TYPE(s64, s16, S64_MAX, true);
   912		TEST_OVERFLOWS_TYPE(s64, s32, S32_MAX, false);
   913		TEST_OVERFLOWS_TYPE(s64, s32, S32_MIN, false);
   914		TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MAX + 1, true);
   915		TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MIN - 1, true);
   916		TEST_OVERFLOWS_TYPE(s64, s32, S64_MAX, true);
   917		TEST_OVERFLOWS_TYPE(s64, s64, S64_MAX, false);
   918		TEST_OVERFLOWS_TYPE(s64, s64, S64_MIN, false);
   919	#endif
   920	#undef TEST_OVERFLOWS_TYPE
   921	}
   922
kernel test robot Sept. 24, 2022, 2:52 p.m. UTC | #2
Hi Gwan-gyeong,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]

url:    https://github.com/intel-lab-lkp/linux/commits/Gwan-gyeong-Mun/Fixes-integer-overflow-or-integer-truncation-issues-in-page-lookups-ttm-place-configuration-and-scatterlist-creation/20220923-163015
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: riscv-randconfig-r036-20220923
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 791a7ae1ba3efd6bca96338e10ffde557ba83920)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/90f09a98b3949d759efe6febd174ed6e26c1a3ab
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Gwan-gyeong-Mun/Fixes-integer-overflow-or-integer-truncation-issues-in-page-lookups-ttm-place-configuration-and-scatterlist-creation/20220923-163015
        git checkout 90f09a98b3949d759efe6febd174ed6e26c1a3ab
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash lib/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:787:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:788:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:788:2: warning: result of comparison of constant 65535 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:218:14: note: expanded from macro 'overflows_type_ret_const_expr'
                   x < 0 || x > type_max(typeof(T)) ? 1 : 0        \
                            ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:805:2: warning: result of comparison of constant 2147483647 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:805:2: warning: result of comparison of constant -2147483648 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:805:2: warning: result of comparison of constant 2147483647 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:805:2: warning: result of comparison of constant -2147483648 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:806:2: warning: result of comparison of constant 2147483647 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:806:2: warning: result of comparison of constant -2147483648 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:806:2: warning: result of comparison of constant 2147483647 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:806:2: warning: result of comparison of constant -2147483648 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:824:2: warning: result of comparison of constant 18446744073709551615 with expression of type 'u32' (aka 'unsigned int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:824:2: warning: result of comparison of constant 18446744073709551615 with expression of type 'u32' (aka 'unsigned int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:825:2: warning: result of comparison of constant 9223372036854775807 with expression of type 'u32' (aka 'unsigned int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:825:2: warning: result of comparison of constant 9223372036854775807 with expression of type 'u32' (aka 'unsigned int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:216:5: note: expanded from macro 'overflows_type_ret_const_expr'
                   x > type_max(typeof(T)) ? 1 : 0                 \
                   ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:860:2: warning: result of comparison of constant 9223372036854775807 with expression of type 's32' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:860:2: warning: result of comparison of constant -9223372036854775808 with expression of type 's32' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
>> lib/overflow_kunit.c:860:2: warning: result of comparison of constant 9223372036854775807 with expression of type 's32' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:860:2: warning: result of comparison of constant -9223372036854775808 with expression of type 's32' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:861:2: warning: result of comparison of constant 9223372036854775807 with expression of type 's32' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:861:2: warning: result of comparison of constant -9223372036854775808 with expression of type 's32' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:733:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, t2) ? true : false;  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:861:2: warning: result of comparison of constant 9223372036854775807 with expression of type 's32' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:34: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                                                ~ ^ ~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:861:2: warning: result of comparison of constant -9223372036854775808 with expression of type 's32' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
           TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   lib/overflow_kunit.c:739:9: note: expanded from macro 'TEST_OVERFLOWS_TYPE'
           __of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/overflow.h:219:7: note: expanded from macro 'overflows_type_ret_const_expr'
                   : x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
                     ~ ^ ~~~~~~~~~~~~~~~~~~~
   54 warnings generated.


vim +824 lib/overflow_kunit.c

   746	
   747		TEST_OVERFLOWS_TYPE(u8, u8, U8_MAX, false);
   748		TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
   749		TEST_OVERFLOWS_TYPE(u8, s8, U8_MAX, true);
   750		TEST_OVERFLOWS_TYPE(u8, s8, S8_MAX, false);
   751		TEST_OVERFLOWS_TYPE(u8, s8, (u8)S8_MAX + 1, true);
   752		TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
   753		TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
   754		TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
   755		TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
   756		TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
   757		TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
   758		TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
   759		TEST_OVERFLOWS_TYPE(s8, u32, S8_MAX, false);
   760		TEST_OVERFLOWS_TYPE(s8, u32, -1, true);
   761		TEST_OVERFLOWS_TYPE(s8, u32, S8_MIN, true);
   762	#if BITS_PER_LONG == 64
   763		TEST_OVERFLOWS_TYPE(s8, u64, S8_MAX, false);
   764		TEST_OVERFLOWS_TYPE(s8, u64, -1, true);
   765		TEST_OVERFLOWS_TYPE(s8, u64, S8_MIN, true);
   766	#endif
   767		TEST_OVERFLOWS_TYPE(s8, s8, S8_MAX, false);
   768		TEST_OVERFLOWS_TYPE(s8, s8, S8_MIN, false);
   769		TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
   770		TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
   771		TEST_OVERFLOWS_TYPE(u16, u8, U8_MAX, false);
   772		TEST_OVERFLOWS_TYPE(u16, u8, (u16)U8_MAX + 1, true);
   773		TEST_OVERFLOWS_TYPE(u16, u8, U16_MAX, true);
   774		TEST_OVERFLOWS_TYPE(u16, s8, S8_MAX, false);
   775		TEST_OVERFLOWS_TYPE(u16, s8, (u16)S8_MAX + 1, true);
   776		TEST_OVERFLOWS_TYPE(u16, s8, U16_MAX, true);
   777		TEST_OVERFLOWS_TYPE(u16, s16, S16_MAX, false);
   778		TEST_OVERFLOWS_TYPE(u16, s16, (u16)S16_MAX + 1, true);
   779		TEST_OVERFLOWS_TYPE(u16, s16, U16_MAX, true);
   780		TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
   781		TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
   782		TEST_OVERFLOWS_TYPE(s16, u8, U8_MAX, false);
   783		TEST_OVERFLOWS_TYPE(s16, u8, (s16)U8_MAX + 1, true);
   784		TEST_OVERFLOWS_TYPE(s16, u8, -1, true);
   785		TEST_OVERFLOWS_TYPE(s16, u8, S16_MIN, true);
   786		TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
   787		TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
   788		TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
   789		TEST_OVERFLOWS_TYPE(s16, u32, S16_MAX, false);
   790		TEST_OVERFLOWS_TYPE(s16, u32, -1, true);
   791		TEST_OVERFLOWS_TYPE(s16, u32, S16_MIN, true);
   792	#if BITS_PER_LONG == 64
   793		TEST_OVERFLOWS_TYPE(s16, u64, S16_MAX, false);
   794		TEST_OVERFLOWS_TYPE(s16, u64, -1, true);
   795		TEST_OVERFLOWS_TYPE(s16, u64, S16_MIN, true);
   796	#endif
   797		TEST_OVERFLOWS_TYPE(s16, s8, S8_MAX, false);
   798		TEST_OVERFLOWS_TYPE(s16, s8, S8_MIN, false);
   799		TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MAX + 1, true);
   800		TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MIN - 1, true);
   801		TEST_OVERFLOWS_TYPE(s16, s8, S16_MAX, true);
   802		TEST_OVERFLOWS_TYPE(s16, s8, S16_MIN, true);
   803		TEST_OVERFLOWS_TYPE(s16, s16, S16_MAX, false);
   804		TEST_OVERFLOWS_TYPE(s16, s16, S16_MIN, false);
   805		TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
   806		TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
   807		TEST_OVERFLOWS_TYPE(u32, u8, U8_MAX, false);
   808		TEST_OVERFLOWS_TYPE(u32, u8, (u32)U8_MAX + 1, true);
   809		TEST_OVERFLOWS_TYPE(u32, u8, U32_MAX, true);
   810		TEST_OVERFLOWS_TYPE(u32, s8, S8_MAX, false);
   811		TEST_OVERFLOWS_TYPE(u32, s8, (u32)S8_MAX + 1, true);
   812		TEST_OVERFLOWS_TYPE(u32, s8, U32_MAX, true);
   813		TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX, false);
   814		TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX + 1, true);
   815		TEST_OVERFLOWS_TYPE(u32, u16, U32_MAX, true);
   816		TEST_OVERFLOWS_TYPE(u32, s16, S16_MAX, false);
   817		TEST_OVERFLOWS_TYPE(u32, s16, (u32)S16_MAX + 1, true);
   818		TEST_OVERFLOWS_TYPE(u32, s16, U32_MAX, true);
   819		TEST_OVERFLOWS_TYPE(u32, u32, U32_MAX, false);
   820		TEST_OVERFLOWS_TYPE(u32, s32, S32_MAX, false);
   821		TEST_OVERFLOWS_TYPE(u32, s32, U32_MAX, true);
   822		TEST_OVERFLOWS_TYPE(u32, s32, (u32)S32_MAX + 1, true);
   823	#if BITS_PER_LONG == 64
 > 824		TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
   825		TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
   826	#endif
   827		TEST_OVERFLOWS_TYPE(s32, u8, U8_MAX, false);
   828		TEST_OVERFLOWS_TYPE(s32, u8, (s32)U8_MAX + 1, true);
   829		TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
   830		TEST_OVERFLOWS_TYPE(s32, u8, -1, true);
   831		TEST_OVERFLOWS_TYPE(s32, u8, S32_MIN, true);
   832		TEST_OVERFLOWS_TYPE(s32, u16, U16_MAX, false);
   833		TEST_OVERFLOWS_TYPE(s32, u16, (s32)U16_MAX + 1, true);
   834		TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
   835		TEST_OVERFLOWS_TYPE(s32, u16, -1, true);
   836		TEST_OVERFLOWS_TYPE(s32, u16, S32_MIN, true);
   837		TEST_OVERFLOWS_TYPE(s32, u32, S32_MAX, false);
   838		TEST_OVERFLOWS_TYPE(s32, u32, -1, true);
   839		TEST_OVERFLOWS_TYPE(s32, u32, S32_MIN, true);
   840	#if BITS_PER_LONG == 64
   841		TEST_OVERFLOWS_TYPE(s32, u64, S32_MAX, false);
   842		TEST_OVERFLOWS_TYPE(s32, u64, -1, true);
   843		TEST_OVERFLOWS_TYPE(s32, u64, S32_MIN, true);
   844	#endif
   845		TEST_OVERFLOWS_TYPE(s32, s8, S8_MAX, false);
   846		TEST_OVERFLOWS_TYPE(s32, s8, S8_MIN, false);
   847		TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MAX + 1, true);
   848		TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MIN - 1, true);
   849		TEST_OVERFLOWS_TYPE(s32, s8, S32_MAX, true);
   850		TEST_OVERFLOWS_TYPE(s32, s8, S32_MIN, true);
   851		TEST_OVERFLOWS_TYPE(s32, s16, S16_MAX, false);
   852		TEST_OVERFLOWS_TYPE(s32, s16, S16_MIN, false);
   853		TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MAX + 1, true);
   854		TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MIN - 1, true);
   855		TEST_OVERFLOWS_TYPE(s32, s16, S32_MAX, true);
   856		TEST_OVERFLOWS_TYPE(s32, s16, S32_MIN, true);
   857		TEST_OVERFLOWS_TYPE(s32, s32, S32_MAX, false);
   858		TEST_OVERFLOWS_TYPE(s32, s32, S32_MIN, false);
   859	#if BITS_PER_LONG == 64
 > 860		TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
   861		TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
   862		TEST_OVERFLOWS_TYPE(u64, u8, U64_MAX, true);
   863		TEST_OVERFLOWS_TYPE(u64, u8, U8_MAX, false);
   864		TEST_OVERFLOWS_TYPE(u64, u8, (u64)U8_MAX + 1, true);
   865		TEST_OVERFLOWS_TYPE(u64, u16, U64_MAX, true);
   866		TEST_OVERFLOWS_TYPE(u64, u16, U16_MAX, false);
   867		TEST_OVERFLOWS_TYPE(u64, u16, (u64)U16_MAX + 1, true);
   868		TEST_OVERFLOWS_TYPE(u64, u32, U64_MAX, true);
   869		TEST_OVERFLOWS_TYPE(u64, u32, U32_MAX, false);
   870		TEST_OVERFLOWS_TYPE(u64, u32, (u64)U32_MAX + 1, true);
   871		TEST_OVERFLOWS_TYPE(u64, u64, U64_MAX, false);
   872		TEST_OVERFLOWS_TYPE(u64, s8, S8_MAX, false);
   873		TEST_OVERFLOWS_TYPE(u64, s8, (u64)S8_MAX + 1, true);
   874		TEST_OVERFLOWS_TYPE(u64, s8, U64_MAX, true);
   875		TEST_OVERFLOWS_TYPE(u64, s16, S16_MAX, false);
   876		TEST_OVERFLOWS_TYPE(u64, s16, (u64)S16_MAX + 1, true);
   877		TEST_OVERFLOWS_TYPE(u64, s16, U64_MAX, true);
   878		TEST_OVERFLOWS_TYPE(u64, s32, S32_MAX, false);
   879		TEST_OVERFLOWS_TYPE(u64, s32, (u64)S32_MAX + 1, true);
   880		TEST_OVERFLOWS_TYPE(u64, s32, U64_MAX, true);
   881		TEST_OVERFLOWS_TYPE(u64, s64, S64_MAX, false);
   882		TEST_OVERFLOWS_TYPE(u64, s64, U64_MAX, true);
   883		TEST_OVERFLOWS_TYPE(u64, s64, (u64)S64_MAX + 1, true);
   884		TEST_OVERFLOWS_TYPE(s64, u8, S64_MAX, true);
   885		TEST_OVERFLOWS_TYPE(s64, u8, S64_MIN, true);
   886		TEST_OVERFLOWS_TYPE(s64, u8, -1, true);
   887		TEST_OVERFLOWS_TYPE(s64, u8, U8_MAX, false);
   888		TEST_OVERFLOWS_TYPE(s64, u8, (s64)U8_MAX + 1, true);
   889		TEST_OVERFLOWS_TYPE(s64, u16, S64_MAX, true);
   890		TEST_OVERFLOWS_TYPE(s64, u16, S64_MIN, true);
   891		TEST_OVERFLOWS_TYPE(s64, u16, -1, true);
   892		TEST_OVERFLOWS_TYPE(s64, u16, U16_MAX, false);
   893		TEST_OVERFLOWS_TYPE(s64, u16, (s64)U16_MAX + 1, true);
   894		TEST_OVERFLOWS_TYPE(s64, u32, S64_MAX, true);
   895		TEST_OVERFLOWS_TYPE(s64, u32, S64_MIN, true);
   896		TEST_OVERFLOWS_TYPE(s64, u32, -1, true);
   897		TEST_OVERFLOWS_TYPE(s64, u32, U32_MAX, false);
   898		TEST_OVERFLOWS_TYPE(s64, u32, (s64)U32_MAX + 1, true);
   899		TEST_OVERFLOWS_TYPE(s64, u64, S64_MAX, false);
   900		TEST_OVERFLOWS_TYPE(s64, u64, S64_MIN, true);
   901		TEST_OVERFLOWS_TYPE(s64, u64, -1, true);
   902		TEST_OVERFLOWS_TYPE(s64, s8, S8_MAX, false);
   903		TEST_OVERFLOWS_TYPE(s64, s8, S8_MIN, false);
   904		TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MAX + 1, true);
   905		TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MIN - 1, true);
   906		TEST_OVERFLOWS_TYPE(s64, s8, S64_MAX, true);
   907		TEST_OVERFLOWS_TYPE(s64, s16, S16_MAX, false);
   908		TEST_OVERFLOWS_TYPE(s64, s16, S16_MIN, false);
   909		TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MAX + 1, true);
   910		TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MIN - 1, true);
   911		TEST_OVERFLOWS_TYPE(s64, s16, S64_MAX, true);
   912		TEST_OVERFLOWS_TYPE(s64, s32, S32_MAX, false);
   913		TEST_OVERFLOWS_TYPE(s64, s32, S32_MIN, false);
   914		TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MAX + 1, true);
   915		TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MIN - 1, true);
   916		TEST_OVERFLOWS_TYPE(s64, s32, S64_MAX, true);
   917		TEST_OVERFLOWS_TYPE(s64, s64, S64_MAX, false);
   918		TEST_OVERFLOWS_TYPE(s64, s64, S64_MIN, false);
   919	#endif
   920	#undef TEST_OVERFLOWS_TYPE
   921	}
   922
Kees Cook Sept. 26, 2022, 12:37 a.m. UTC | #3
On Fri, Sep 23, 2022 at 11:26:22AM +0300, Gwan-gyeong Mun wrote:
> Adds assert_same_type and assert_same_typable macros to catch type
> mis-match while compiling. The existing typecheck() macro outputs build
> warnings, but the newly added assert_same_type() macro uses the
> static_assert macro (which uses _Static_assert keyword and it introduced
> in C11) to generate a build break when the types are different and can be
> used to detect explicit build errors. Unlike the assert_same_type() macro,
> assert_same_typable() macro allows a constant value as the second argument.
> Since static_assert is used at compile time and it requires
> constant-expression as an argument [1][2], overflows_type_ret_const_expr()
> is newly added. There is overflows_type() that has the same behavior, but
> the macro uses __builtin_add_overflow() internally, and
> __builtin_add_overflows returns a bool type [3], so it is difficult to use
> as an argument of _Static_assert. The assert_same_type and
> assert_same_typable macros have been added to compiler_types.h, but the
> overflows_type_ret_const_expr macro has been added to overflow.h
> So, overflow.h has to be included to use assert_same_typable which
> internally uses overflows_type_ret_const_expr.
> And it adds unit tests for overflows_type, overflows_type_ret_const_expr,
> assert_same_type and assert_same_typable. The overflows_type has been added
> as well to compare whether the overflows_type_ret_const_expr unit test has
> the same as the result.

I spent some time rewriting the code in this patch. I think it's really
close, but I wanted to tweak how things were being defined, naming, etc.

Notes below, and I'll send my proposed patch separately...

> [...]
> +#define overflows_type_ret_const_expr(x,T) (			\

For the "overflows_type" defines, I think this reads a bit better:

#define __overflows_type_constexpr(x, T) (                      \
        is_unsigned_type(typeof(x)) ?                           \
                (x) > type_max(typeof(T)) ? 1 : 0               \
        : is_unsigned_type(typeof(T)) ?                         \
                (x) < 0 || (x) > type_max(typeof(T)) ? 1 : 0    \
                : (x) < type_min(typeof(T)) ||                  \
                  (x) > type_max(typeof(T)) ? 1 : 0 )

#define __overflows_type(x, T)          ({      \
        typeof(T) v = 0;                        \
        check_add_overflow((x), v, &v);         \
})

#define overflows_type(n, T)                                    \
        __builtin_choose_expr(__is_constexpr(n),                \
                              __overflows_type_constexpr(n, T), \
                              __overflows_type(n, T))

> [...]
> +/**
> + * assert_same_type - abort compilation if the first argument's data type and
> + *                    the second argument's data type are not the same
> + * @t1: data type or variable
> + * @t2: data type or variable
> + *
> + * The first and second arguments can be data types or variables or mixed (the
> + * first argument is the data type and the second argument is variable or vice
> + * versa). It determines whether the first argument's data type and the second
> + * argument's data type are the same while compiling, and it aborts compilation
> + * if the two types are not the same.
> + * See also assert_same_typable().
> + */
> +#define assert_same_type(t1, t2) static_assert(__same_type(t1, t2))

I still think I'd rather avoid a define for this. It doesn't seem worth
4 characters of savings to just have to type it out:

	static_assert(__same_type(a, b))

> [...]
> +#define assert_same_typable(t, n) static_assert(			       \
> +		__builtin_choose_expr(__builtin_constant_p(n),		       \
> +				      overflows_type_ret_const_expr(n,t) == 0, \
> +				      __same_type(t, n)))

This one I'd like to convert into something closer in naming convention to
"__same_type". Also note that "__builtin_constant_p()" doesn't actually
work here: it needs to be __is_constexpr(). So, I propose:

#define __castable_to_type(n, T)				\
		__builtin_choose_expr(__is_constexpr(n),	\
			__overflows_type_constexpr(n, T),	\
			__same_type(n, T))

Then we can do:

	static_assert(__castable_to_type(INT_MAX, size_t));

> [...[
> +static void overflows_type_test(struct kunit *test)
> +{
> +/* Args are: first type, secound type, value, overflow expected */
> +#define TEST_OVERFLOWS_TYPE(t1, t2, v, of) do {				\
> +	t1 __t1 = v;							\
> +	t2 __t2;							\
> +	bool __of;							\
> +	__of = overflows_type(v, t2);					\
> +	if (__of != of) {						\
> +		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
> +			"expected overflows_type(%s, %s) to%s overflow\n", \
> +			#v, #t2, of ? "" : " not");			\
> +	}								\
> [...]
> +	__of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
> +	if (__of != of) {						\
> +		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
> +			"expected overflows_type_ret_const_expr(%s, %s) to%s overflow\n", \
> +			#t1" __t1 = "#v, #t2" __t2", of ? "" : " not");	\
> +	}								\

These tests are excellent! I've adapted them a little bit to avoid some
of their internal redundancy. (i.e. the above blocks are basically
almost entire the same, etc).

-Kees
diff mbox series

Patch

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 7713d7bcdaea..c631107e93b1 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -244,6 +244,7 @@  static inline void *offset_to_ptr(const int *off)
  * bool and also pointer types.
  */
 #define is_signed_type(type) (((type)(-1)) < (__force type)1)
+#define is_unsigned_type(type) (!is_signed_type(type))
 
 /*
  * This is needed in functions which generate the stack canary, see
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 4f2a819fd60a..e6f5d68e5eba 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -294,6 +294,49 @@  struct ftrace_likely_data {
 /* Are two types/vars the same type (ignoring qualifiers)? */
 #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
 
+/**
+ * assert_same_type - abort compilation if the first argument's data type and
+ *                    the second argument's data type are not the same
+ * @t1: data type or variable
+ * @t2: data type or variable
+ *
+ * The first and second arguments can be data types or variables or mixed (the
+ * first argument is the data type and the second argument is variable or vice
+ * versa). It determines whether the first argument's data type and the second
+ * argument's data type are the same while compiling, and it aborts compilation
+ * if the two types are not the same.
+ * See also assert_same_typable().
+ */
+#define assert_same_type(t1, t2) static_assert(__same_type(t1, t2))
+
+/**
+ * assert_same_typable - abort compilation if the first argument's data type and
+ *                       the second argument's data type are not the same
+ * @t: data type or variable
+ * @n: data type or variable or constant value
+ *
+ * The first and second arguments can be data types or variables or mixed (the
+ * first argument is the data type and the second argument is variable or vice
+ * versa). Unlike the assert_same_type() macro, this macro allows a constant
+ * value as the second argument. And if the second argument is a constant
+ * value, it checks overflows between the first argument's data type and the
+ * second argument's constant value to check whether overflow can occur when
+ * assigning the second argument to the variable of the first argument. And it
+ * aborts compilation if the overflow can occur. Since static assert used at
+ * compile time requires constant-expression as an argument,
+ * overflows_type_ret_const_expr() is used internally instead of
+ * overflows_type(). When a constant value is not used as a second argument, it
+ * determines whether the first argument's data type and the second argument's
+ * data type are the same while compiling, and it aborts compilation if the two
+ * types are not the same.
+ * See also assert_same_type(), overflows_type_ret_const_expr() and
+ * overflows_type().
+ */
+#define assert_same_typable(t, n) static_assert(			       \
+		__builtin_choose_expr(__builtin_constant_p(n),		       \
+				      overflows_type_ret_const_expr(n,t) == 0, \
+				      __same_type(t, n)))
+
 /*
  * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
  *			       non-scalar types unchanged.
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 0eca3d8281b2..6e481ad2e46e 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -191,6 +191,33 @@  static inline bool __must_check __must_check_overflow(bool overflow)
 	check_add_overflow((x), v, &v);			\
 }))
 
+/**
+ * overflows_type_ret_const_expr - helper for checking the overflows between
+ *                                 value, variables, or data type
+ *
+ * @x: source constant value or variable for overflow check
+ * @T: destination variable or data type for overflow check
+ *
+ * It compares the value, variables, or data type between the first and second
+ * argument to check whether overflow can occur when assigning the first
+ * argument to the variable of the second argument data type. Source and
+ * Destination can be different data types. Unlike overflows_type(), it returns
+ * a constant-expression value. It is recommended to use this macro only when a
+ * constant-expression value is absolutely necessary at compile time. In other
+ * cases, it is recommended to use overflows_type().
+ *
+ * See also overflows_type() and assert_same_typable().
+ *
+ * Returns:
+ * 1 if overflow can occur, 0 otherwise.
+ */
+#define overflows_type_ret_const_expr(x,T) (			\
+	is_unsigned_type(typeof(x)) ? 				\
+		x > type_max(typeof(T)) ? 1 : 0			\
+	: is_unsigned_type(typeof(T)) ? 			\
+		x < 0 || x > type_max(typeof(T)) ? 1 : 0	\
+		: x < type_min(typeof(T)) || x > type_max(typeof(T)) ? 1 : 0 )
+
 /**
  * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
  *
diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c
index 0d98c9bc75da..a9c99a116e3c 100644
--- a/lib/overflow_kunit.c
+++ b/lib/overflow_kunit.c
@@ -687,6 +687,287 @@  static void overflow_size_helpers_test(struct kunit *test)
 #undef check_one_size_helper
 }
 
+static void overflows_type_test(struct kunit *test)
+{
+/* Args are: first type, secound type, value, overflow expected */
+#define TEST_OVERFLOWS_TYPE(t1, t2, v, of) do {				\
+	t1 __t1 = v;							\
+	t2 __t2;							\
+	bool __of;							\
+	__of = overflows_type(v, t2);					\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected overflows_type(%s, %s) to%s overflow\n", \
+			#v, #t2, of ? "" : " not");			\
+	}								\
+	__of = overflows_type(v, __t2);					\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected overflows_type(%s, %s) to%s overflow\n", \
+			#v, #t2" __t2", of ? "" : " not");		\
+	}								\
+	__of = overflows_type(__t1, t2);				\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected overflows_type(%s, %s) to%s overflow\n", \
+			#t1" __t1 = "#v, #t2, of ? "" : " not");		\
+	}								\
+	__of = overflows_type(__t1, __t2);				\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected overflows_type(%s, %s) to%s overflow\n", \
+			#t1" __t1 = "#v, #t2" __t2", of ? "" : " not");	\
+	}								\
+	__of = overflows_type_ret_const_expr(v, t2) ? true : false;	\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected overflows_type_ret_const_expr(%s, %s) to%s overflow\n", \
+			#v, #t2, of ? "" : " not");			\
+	}								\
+	__of = overflows_type_ret_const_expr(v, __t2) ? true : false;	\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected overflows_type_ret_const_expr(%s, %s) to%s overflow\n", \
+			#v, #t2" __t2", of ? "" : " not");		\
+	}								\
+	__of = overflows_type_ret_const_expr(__t1, t2) ? true : false;	\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected overflows_type_ret_const_expr(%s, %s) to%s overflow\n", \
+			#t1" __t1 = "#v, #t2, of ? "" : " not");		\
+	}								\
+	__of = overflows_type_ret_const_expr(__t1, __t2) ? true : false;\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected overflows_type_ret_const_expr(%s, %s) to%s overflow\n", \
+			#t1" __t1 = "#v, #t2" __t2", of ? "" : " not");	\
+	}								\
+} while(0)
+
+	TEST_OVERFLOWS_TYPE(u8, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u8, s8, U8_MAX, true);
+	TEST_OVERFLOWS_TYPE(u8, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u8, s8, (u8)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
+	TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
+	TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
+	TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
+	TEST_OVERFLOWS_TYPE(s8, u32, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u32, -1, true);
+	TEST_OVERFLOWS_TYPE(s8, u32, S8_MIN, true);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(s8, u64, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u64, -1, true);
+	TEST_OVERFLOWS_TYPE(s8, u64, S8_MIN, true);
+#endif
+	TEST_OVERFLOWS_TYPE(s8, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, s8, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(u16, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u16, u8, (u16)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u16, u8, U16_MAX, true);
+	TEST_OVERFLOWS_TYPE(u16, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u16, s8, (u16)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u16, s8, U16_MAX, true);
+	TEST_OVERFLOWS_TYPE(u16, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u16, s16, (u16)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u16, s16, U16_MAX, true);
+	TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u8, (s16)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s16, u8, -1, true);
+	TEST_OVERFLOWS_TYPE(s16, u8, S16_MIN, true);
+	TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
+	TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
+	TEST_OVERFLOWS_TYPE(s16, u32, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u32, -1, true);
+	TEST_OVERFLOWS_TYPE(s16, u32, S16_MIN, true);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(s16, u64, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u64, -1, true);
+	TEST_OVERFLOWS_TYPE(s16, u64, S16_MIN, true);
+#endif
+	TEST_OVERFLOWS_TYPE(s16, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, s8, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s16, s8, S16_MAX, true);
+	TEST_OVERFLOWS_TYPE(s16, s8, S16_MIN, true);
+	TEST_OVERFLOWS_TYPE(s16, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, s16, S16_MIN, false);
+	TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
+	TEST_OVERFLOWS_TYPE(u32, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, u8, (u32)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u32, u8, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s8, (u32)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u32, s8, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u32, u16, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s16, (u32)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u32, s16, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, u32, U32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s32, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, s32, (u32)S32_MAX + 1, true);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
+#endif
+	TEST_OVERFLOWS_TYPE(s32, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, u8, (s32)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
+	TEST_OVERFLOWS_TYPE(s32, u8, -1, true);
+	TEST_OVERFLOWS_TYPE(s32, u8, S32_MIN, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, u16, (s32)U16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, -1, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, S32_MIN, true);
+	TEST_OVERFLOWS_TYPE(s32, u32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, u32, -1, true);
+	TEST_OVERFLOWS_TYPE(s32, u32, S32_MIN, true);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(s32, u64, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, u64, -1, true);
+	TEST_OVERFLOWS_TYPE(s32, u64, S32_MIN, true);
+#endif
+	TEST_OVERFLOWS_TYPE(s32, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, s8, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s32, s8, S32_MAX, true);
+	TEST_OVERFLOWS_TYPE(s32, s8, S32_MIN, true);
+	TEST_OVERFLOWS_TYPE(s32, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, s16, S16_MIN, false);
+	TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s32, s16, S32_MAX, true);
+	TEST_OVERFLOWS_TYPE(s32, s16, S32_MIN, true);
+	TEST_OVERFLOWS_TYPE(s32, s32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, s32, S32_MIN, false);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
+	TEST_OVERFLOWS_TYPE(u64, u8, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, u8, (u64)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, u16, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, u16, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, u16, (u64)U16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, u32, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, u32, U32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, u32, (u64)U32_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, u64, U64_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s8, (u64)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, s8, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s16, (u64)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, s16, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, s32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s32, (u64)S32_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, s32, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, s64, S64_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s64, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, s64, (u64)S64_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, u8, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, u8, S64_MIN, true);
+	TEST_OVERFLOWS_TYPE(s64, u8, -1, true);
+	TEST_OVERFLOWS_TYPE(s64, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, u8, (s64)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, u16, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, u16, S64_MIN, true);
+	TEST_OVERFLOWS_TYPE(s64, u16, -1, true);
+	TEST_OVERFLOWS_TYPE(s64, u16, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, u16, (s64)U16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, u32, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, u32, S64_MIN, true);
+	TEST_OVERFLOWS_TYPE(s64, u32, -1, true);
+	TEST_OVERFLOWS_TYPE(s64, u32, U32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, u32, (s64)U32_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, u64, S64_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, u64, S64_MIN, true);
+	TEST_OVERFLOWS_TYPE(s64, u64, -1, true);
+	TEST_OVERFLOWS_TYPE(s64, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, s8, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s8, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, s16, S16_MIN, false);
+	TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s16, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, s32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, s32, S32_MIN, false);
+	TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s32, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, s64, S64_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, s64, S64_MIN, false);
+#endif
+#undef TEST_OVERFLOWS_TYPE
+}
+
+static void assert_same_type_test(struct kunit *test)
+{
+/* Arg is: type */
+#define TEST_ASSERT_SAME_TYPE(t) do {	\
+   typeof(t) __t1 = type_max(t);	\
+   typeof(t) __t2 = type_min(t);	\
+   assert_same_type(t, t);		\
+   assert_same_type(t, __t1);		\
+   assert_same_type(__t1, t);		\
+   assert_same_type(__t1, __t2);	\
+} while (0)
+
+/* Arg is: type */
+#define TEST_ASSERT_SAME_TYPABLE(t) do {	\
+   typeof(t) __t1 = type_max(t);		\
+   typeof(t) __t2 = type_min(t);		\
+   assert_same_typable(t, __t1);		\
+   assert_same_typable(t, type_max(t));		\
+   assert_same_typable(t, type_min(t));		\
+   assert_same_typable(__t1, type_max(t));	\
+   assert_same_typable(__t1, type_min(t));	\
+   assert_same_typable(__t1, __t2);		\
+} while (0)
+
+	TEST_ASSERT_SAME_TYPE(u8);
+	TEST_ASSERT_SAME_TYPE(u16);
+	TEST_ASSERT_SAME_TYPE(u32);
+	TEST_ASSERT_SAME_TYPE(s8);
+	TEST_ASSERT_SAME_TYPE(s16);
+	TEST_ASSERT_SAME_TYPE(s32);
+	TEST_ASSERT_SAME_TYPABLE(u8);
+	TEST_ASSERT_SAME_TYPABLE(u16);
+	TEST_ASSERT_SAME_TYPABLE(u32);
+	TEST_ASSERT_SAME_TYPABLE(s8);
+	TEST_ASSERT_SAME_TYPABLE(s16);
+	TEST_ASSERT_SAME_TYPABLE(s32);
+
+#if BITS_PER_LONG == 64
+	TEST_ASSERT_SAME_TYPE(u64);
+	TEST_ASSERT_SAME_TYPE(s64);
+	TEST_ASSERT_SAME_TYPABLE(u64);
+	TEST_ASSERT_SAME_TYPABLE(s64);
+#endif
+
+#undef TEST_ASSERT_SAME_TYPABLE
+#undef TEST_ASSERT_SAME_TYPE
+}
+
 static struct kunit_case overflow_test_cases[] = {
 	KUNIT_CASE(u8_u8__u8_overflow_test),
 	KUNIT_CASE(s8_s8__s8_overflow_test),
@@ -706,6 +987,8 @@  static struct kunit_case overflow_test_cases[] = {
 	KUNIT_CASE(overflow_shift_test),
 	KUNIT_CASE(overflow_allocation_test),
 	KUNIT_CASE(overflow_size_helpers_test),
+	KUNIT_CASE(overflows_type_test),
+	KUNIT_CASE(assert_same_type_test),
 	{}
 };