It adds assert_type and assert_typable macros to catch type mis-match while compiling. The existing typecheck() macro outputs build warnings, but the newly added assert_type() macro uses the _Static_assert() keyword (which is 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_type() macro, assert_typable() macro allows a constant value as the second argument.
Suggested-by: Kees Cook <keesc...@chromium.org> Signed-off-by: Gwan-gyeong Mun <gwan-gyeong....@intel.com> Cc: Thomas Hellström <thomas.hellst...@linux.intel.com> Cc: Matthew Auld <matthew.a...@intel.com> Cc: Nirmoy Das <nirmoy....@intel.com> Cc: Jani Nikula <jani.nik...@intel.com> Cc: Andi Shyti <andi.sh...@linux.intel.com> Cc: Mauro Carvalho Chehab <mche...@kernel.org> Cc: Andrzej Hajda <andrzej.ha...@intel.com> Cc: Kees Cook <keesc...@chromium.org> --- include/linux/compiler_types.h | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 4f2a819fd60a..19cc125918bb 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -294,6 +294,45 @@ 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_type - break compile 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 breaks compile if + * the two types are not the same. + * See also assert_typable(). + */ +#define assert_type(t1, t2) _Static_assert(__same_type(t1, t2)) + +/** + * assert_typable - break compile 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_type() macro, this macro allows a constant value + * as the second argument. And if the second argument is a constant value, it + * always passes. And it doesn't mean that the types are explicitly the same. + * When a constant value is used as the second argument, if you need an + * overflow check when assigning a constant value to a variable of the type of + * the first argument, you can use the overflows_type() macro. 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 breaks compile if the two types are not the same. + * See also assert_type() and overflows_type(). + */ +#define assert_typable(t, n) _Static_assert(__builtin_constant_p(n) || \ + __same_type(t, typeof(n))) + /* * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving * non-scalar types unchanged. -- 2.37.1