* Re: [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) [not found] <202601150001.sKSN644a-lkp@intel.com> @ 2026-01-15 19:28 ` Thomas Gleixner 2026-01-15 21:11 ` Peter Zijlstra 0 siblings, 1 reply; 11+ messages in thread From: Thomas Gleixner @ 2026-01-15 19:28 UTC (permalink / raw) To: kernel test robot, Ian Rogers Cc: oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Peter Zijlstra, Marco Elver On Thu, Jan 15 2026 at 00:36, kernel test robot wrote: Cc+ sparse folks. > sparse warnings: (new ones prefixed by >>) >>> net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) @@ expected void * @@ got restricted __be64 const * @@ > net/rds/ib_cm.c:96:35: sparse: expected void * > net/rds/ib_cm.c:96:35: sparse: got restricted __be64 const * > net/rds/ib_cm.c:103:27: sparse: sparse: incorrect type in argument 1 (different modifiers) @@ expected void * @@ got restricted __be64 const * @@ > net/rds/ib_cm.c:103:27: sparse: expected void * > net/rds/ib_cm.c:103:27: sparse: got restricted __be64 const * After staring a while at it, it turns out that get_unaligned_t(), which uses __unqual_scalar_typeof() to get an unqualified type makes sparse unhappy when the data type is __be64 (or any other __beNN variant). __beNN is annotated with __attribute__((bitwise)) when sparse is invoked (#ifdef CHECKER). That allows sparse to detect incompatible math operations with __beNN variables. That annotation also causes the type comparison in the sparse _Generic() evaluation to fail so that it ends up with the default, i.e. the original qualified type of a 'const __beNN' pointer. That then ends up as the first pointer argument to builtin_memcpy(), which obviously causes the above sparse warnings. The easiest solution would be to force cast the pointer to void * when CHECKER is defined, but that reduces coverage. I've come up with the below, but it's clearly a hack... __CAST_SPARSE() is required as sparse otherwise complains about storing __u64 in __be64. Thanks, tglx --- include/linux/compiler_types.h | 10 ++++++++++ include/vdso/unaligned.h | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -577,6 +577,15 @@ struct ftrace_likely_data { unsigned type: (unsigned type)0, \ signed type: (signed type)0 +#ifdef __CHECKER__ +#define __be_types_expr_cases() \ + __be16: (__u16)0, \ + __be32: (__u32)0, \ + __be64: (__u64)0, +#else +#define __be_types_expr_cases() +#endif + #define __unqual_scalar_typeof(x) typeof( \ _Generic((x), \ char: (char)0, \ @@ -585,6 +594,7 @@ struct ftrace_likely_data { __scalar_type_to_expr_cases(int), \ __scalar_type_to_expr_cases(long), \ __scalar_type_to_expr_cases(long long), \ + __be_types_expr_cases() \ default: (x))) /* Is this type a native word size -- useful for atomic operations */ --- a/include/vdso/unaligned.h +++ b/include/vdso/unaligned.h @@ -4,6 +4,12 @@ #include <linux/compiler_types.h> +#ifdef __CHECKER__ +#define __CAST_SPARSE(type) (type __force) +#else +#define __CAST_SPARSE(type) +#endif + /** * __get_unaligned_t - read an unaligned value from memory. * @type: the type to load from the pointer. @@ -17,12 +23,12 @@ * expression rather than type, a pointer is used to avoid warnings about mixing * the use of 0 and NULL. The void* cast silences ubsan warnings. */ -#define __get_unaligned_t(type, ptr) ({ \ - type *__get_unaligned_ctrl_type __always_unused = NULL; \ +#define __get_unaligned_t(type, ptr) ({ \ + type *__get_unaligned_ctrl_type __always_unused = NULL; \ __unqual_scalar_typeof(*__get_unaligned_ctrl_type) __get_unaligned_val; \ - __builtin_memcpy(&__get_unaligned_val, (void *)(ptr), \ - sizeof(__get_unaligned_val)); \ - __get_unaligned_val; \ + __builtin_memcpy(&__get_unaligned_val, (void *)(ptr), \ + sizeof(__get_unaligned_val)); \ + __CAST_SPARSE(type) __get_unaligned_val; \ }) /** ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) 2026-01-15 19:28 ` [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) Thomas Gleixner @ 2026-01-15 21:11 ` Peter Zijlstra 2026-01-15 21:19 ` Linus Torvalds 2026-01-15 23:01 ` Thomas Gleixner 0 siblings, 2 replies; 11+ messages in thread From: Peter Zijlstra @ 2026-01-15 21:11 UTC (permalink / raw) To: Thomas Gleixner Cc: kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Thu, Jan 15, 2026 at 08:28:51PM +0100, Thomas Gleixner wrote: > On Thu, Jan 15 2026 at 00:36, kernel test robot wrote: > > Cc+ sparse folks. > > > sparse warnings: (new ones prefixed by >>) > >>> net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) @@ expected void * @@ got restricted __be64 const * @@ > > net/rds/ib_cm.c:96:35: sparse: expected void * > > net/rds/ib_cm.c:96:35: sparse: got restricted __be64 const * > > net/rds/ib_cm.c:103:27: sparse: sparse: incorrect type in argument 1 (different modifiers) @@ expected void * @@ got restricted __be64 const * @@ > > net/rds/ib_cm.c:103:27: sparse: expected void * > > net/rds/ib_cm.c:103:27: sparse: got restricted __be64 const * > > After staring a while at it, it turns out that get_unaligned_t(), which > uses __unqual_scalar_typeof() to get an unqualified type makes sparse > unhappy when the data type is __be64 (or any other __beNN variant). > > __beNN is annotated with __attribute__((bitwise)) when sparse is invoked > (#ifdef CHECKER). That allows sparse to detect incompatible math > operations with __beNN variables. > Per: https://git.kernel.org/pub/scm/devel/sparse/sparse-dev.git/commit/?id=dc9efe442b8949234a6599fdc94dc7221dd040e1 it seems Sparse now knows about __typeof_unqual__; and it looks like the implementation does what you want here (although I've not tested it). Something like so perhaps, which then mandates the very latest Sparse. --- diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 04487c9bd751..7e0583ceb49f 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -232,11 +232,8 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, /* * Use __typeof_unqual__() when available. - * - * XXX: Remove test for __CHECKER__ once - * sparse learns about __typeof_unqual__(). */ -#if CC_HAS_TYPEOF_UNQUAL && !defined(__CHECKER__) +#if CC_HAS_TYPEOF_UNQUAL || defined(__CHECKER__) # define USE_TYPEOF_UNQUAL 1 #endif diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index d3318a3c2577..a37d832d99a8 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -569,6 +569,7 @@ struct ftrace_likely_data { * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving * non-scalar types unchanged. */ +#ifndef USE_TYPEOF_UNQUAL /* * Prefer C11 _Generic for better compile-times and simpler code. Note: 'char' * is not type-compatible with 'signed char', and we define a separate case. @@ -586,6 +587,9 @@ struct ftrace_likely_data { __scalar_type_to_expr_cases(long), \ __scalar_type_to_expr_cases(long long), \ default: (x))) +#else +#define __unqual_scalar_typeof(x) __typeof_unqual__(x) +#endif /* Is this type a native word size -- useful for atomic operations */ #define __native_word(t) \ ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) 2026-01-15 21:11 ` Peter Zijlstra @ 2026-01-15 21:19 ` Linus Torvalds 2026-01-15 21:30 ` Peter Zijlstra 2026-01-15 23:01 ` Thomas Gleixner 1 sibling, 1 reply; 11+ messages in thread From: Linus Torvalds @ 2026-01-15 21:19 UTC (permalink / raw) To: Peter Zijlstra Cc: Thomas Gleixner, kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Thu, 15 Jan 2026 at 13:13, Peter Zijlstra <peterz@infradead.org> wrote: > > Something like so perhaps, which then mandates the very latest Sparse. Ack. We want that compiler_tpes.h change for the real compilers that support __typeof_unqual__ anyway. Eventually we can just force that everywhere, but as Al pointed out in another thread, we're not quite there yet (ie we'd need clang-19.0.1 and gcc-8.4 to be able to just switch entirely over to __typeof_unqual__). For sparse users, I think we should have the policy that we just don't support older versions at all, since it just gets too painful. Linus ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) 2026-01-15 21:19 ` Linus Torvalds @ 2026-01-15 21:30 ` Peter Zijlstra 2026-01-15 23:03 ` Linus Torvalds 0 siblings, 1 reply; 11+ messages in thread From: Peter Zijlstra @ 2026-01-15 21:30 UTC (permalink / raw) To: Linus Torvalds Cc: Thomas Gleixner, kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Thu, Jan 15, 2026 at 01:19:14PM -0800, Linus Torvalds wrote: > Eventually we can just force that everywhere, but as Al pointed out in > another thread, we're not quite there yet (ie we'd need clang-19.0.1 > and gcc-8.4 to be able to just switch entirely over to > __typeof_unqual__). GCC-14 :-/ The GCC-8.4 one was the function return value trick. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) 2026-01-15 21:30 ` Peter Zijlstra @ 2026-01-15 23:03 ` Linus Torvalds 2026-01-16 8:28 ` Peter Zijlstra 0 siblings, 1 reply; 11+ messages in thread From: Linus Torvalds @ 2026-01-15 23:03 UTC (permalink / raw) To: Peter Zijlstra Cc: Thomas Gleixner, kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Thu, 15 Jan 2026 at 13:31, Peter Zijlstra <peterz@infradead.org> wrote: > > GCC-14 :-/ The GCC-8.4 one was the function return value trick. Right you are. And yeah, us moving on to gcc-14 as a minimum version is not imminent. Still, while we can't force it, lots of distros are on gcc-15, so while we'd have the _Generic() macro as a fallback for older versions, at least most developers would hopefully get the nice clean modern __typeof_unqual__ thing... Linus ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) 2026-01-15 23:03 ` Linus Torvalds @ 2026-01-16 8:28 ` Peter Zijlstra 0 siblings, 0 replies; 11+ messages in thread From: Peter Zijlstra @ 2026-01-16 8:28 UTC (permalink / raw) To: Linus Torvalds Cc: Thomas Gleixner, kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Thu, Jan 15, 2026 at 03:03:52PM -0800, Linus Torvalds wrote: > On Thu, 15 Jan 2026 at 13:31, Peter Zijlstra <peterz@infradead.org> wrote: > > > > GCC-14 :-/ The GCC-8.4 one was the function return value trick. > > Right you are. And yeah, us moving on to gcc-14 as a minimum version > is not imminent. > > Still, while we can't force it, lots of distros are on gcc-15, so > while we'd have the _Generic() macro as a fallback for older versions, > at least most developers would hopefully get the nice clean modern > __typeof_unqual__ thing... Absolutely. I'll try and make it happen if tglx doesn't. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) 2026-01-15 21:11 ` Peter Zijlstra 2026-01-15 21:19 ` Linus Torvalds @ 2026-01-15 23:01 ` Thomas Gleixner 2026-01-16 11:25 ` Thomas Gleixner 1 sibling, 1 reply; 11+ messages in thread From: Thomas Gleixner @ 2026-01-15 23:01 UTC (permalink / raw) To: Peter Zijlstra Cc: kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Thu, Jan 15 2026 at 22:11, Peter Zijlstra wrote: > On Thu, Jan 15, 2026 at 08:28:51PM +0100, Thomas Gleixner wrote: >> On Thu, Jan 15 2026 at 00:36, kernel test robot wrote: >> >> Cc+ sparse folks. >> >> > sparse warnings: (new ones prefixed by >>) >> >>> net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) @@ expected void * @@ got restricted __be64 const * @@ >> > net/rds/ib_cm.c:96:35: sparse: expected void * >> > net/rds/ib_cm.c:96:35: sparse: got restricted __be64 const * >> > net/rds/ib_cm.c:103:27: sparse: sparse: incorrect type in argument 1 (different modifiers) @@ expected void * @@ got restricted __be64 const * @@ >> > net/rds/ib_cm.c:103:27: sparse: expected void * >> > net/rds/ib_cm.c:103:27: sparse: got restricted __be64 const * >> >> After staring a while at it, it turns out that get_unaligned_t(), which >> uses __unqual_scalar_typeof() to get an unqualified type makes sparse >> unhappy when the data type is __be64 (or any other __beNN variant). >> >> __beNN is annotated with __attribute__((bitwise)) when sparse is invoked >> (#ifdef CHECKER). That allows sparse to detect incompatible math >> operations with __beNN variables. >> > > Per: > > https://git.kernel.org/pub/scm/devel/sparse/sparse-dev.git/commit/?id=dc9efe442b8949234a6599fdc94dc7221dd040e1 > > it seems Sparse now knows about __typeof_unqual__; and it looks like the > implementation does what you want here (although I've not tested it). > > Something like so perhaps, which then mandates the very latest Sparse. I tried that before and sparse is still upset: net/rds/ib_cm.c:96:35: warning: incorrect type in argument 1 (different modifiers) net/rds/ib_cm.c:96:35: expected void * net/rds/ib_cm.c:96:35: got restricted __be64 const * net/rds/ib_cm.c:103:27: warning: incorrect type in argument 1 (different modifiers) net/rds/ib_cm.c:103:27: expected void * net/rds/ib_cm.c:103:27: got restricted __be64 const * This time I looked deeper and it seems that USE_TYPEOF_UNQUAL is not set. If I force it to be set and use a proper compiler and top of tree sparse, everything seems to be happy. Figuring that out is something for tomorrow... Thanks, tglx ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) 2026-01-15 23:01 ` Thomas Gleixner @ 2026-01-16 11:25 ` Thomas Gleixner 2026-01-16 18:18 ` [PATCH] compiler: Use __typeof_unqual__() for __unqual_scalar_typeof() Thomas Gleixner 0 siblings, 1 reply; 11+ messages in thread From: Thomas Gleixner @ 2026-01-16 11:25 UTC (permalink / raw) To: Peter Zijlstra Cc: kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Fri, Jan 16 2026 at 00:01, Thomas Gleixner wrote: > This time I looked deeper and it seems that USE_TYPEOF_UNQUAL is not > set. > > If I force it to be set and use a proper compiler and top of tree > sparse, everything seems to be happy. > > Figuring that out is something for tomorrow... USE_TYPEOF_UNQUAL is set _after_ the __unqual_scalar muck is processed... Updated fix below. Thanks, tglx --- include/linux/compiler.h | 10 ---------- include/linux/compiler_types.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -231,16 +231,6 @@ void ftrace_likely_update(struct ftrace_ "must be non-C-string (not NUL-terminated)") /* - * Use __typeof_unqual__() when available. - * - * XXX: Remove test for __CHECKER__ once - * sparse learns about __typeof_unqual__(). - */ -#if CC_HAS_TYPEOF_UNQUAL && !defined(__CHECKER__) -# define USE_TYPEOF_UNQUAL 1 -#endif - -/* * Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof * operator when available, to return an unqualified type of the exp. */ --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -562,6 +562,13 @@ struct ftrace_likely_data { #define asm_inline asm #endif +/* + * Use __typeof_unqual__() when available. + */ +#if CC_HAS_TYPEOF_UNQUAL || defined(__CHECKER__) +# define USE_TYPEOF_UNQUAL 1 +#endif + /* Are two types/vars the same type (ignoring qualifiers)? */ #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) @@ -569,6 +576,7 @@ struct ftrace_likely_data { * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving * non-scalar types unchanged. */ +#ifndef USE_TYPEOF_UNQUAL /* * Prefer C11 _Generic for better compile-times and simpler code. Note: 'char' * is not type-compatible with 'signed char', and we define a separate case. @@ -586,6 +594,9 @@ struct ftrace_likely_data { __scalar_type_to_expr_cases(long), \ __scalar_type_to_expr_cases(long long), \ default: (x))) +#else +#define __unqual_scalar_typeof(x) __typeof_unqual__(x) +#endif /* Is this type a native word size -- useful for atomic operations */ #define __native_word(t) \ ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] compiler: Use __typeof_unqual__() for __unqual_scalar_typeof() 2026-01-16 11:25 ` Thomas Gleixner @ 2026-01-16 18:18 ` Thomas Gleixner 2026-01-17 5:25 ` Ian Rogers 2026-02-25 8:15 ` Dan Carpenter 0 siblings, 2 replies; 11+ messages in thread From: Thomas Gleixner @ 2026-01-16 18:18 UTC (permalink / raw) To: Peter Zijlstra Cc: kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver From: Peter Zijlstra <peterz@infradead.org> The recent changes to get_unaligned() resulted in a new sparse warning: net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) @@ expected void * @@ got restricted __be64 const * @@ net/rds/ib_cm.c:96:35: sparse: expected void * net/rds/ib_cm.c:96:35: sparse: got restricted __be64 const * The updated get_unaligned_t() uses __unqual_scalar_typeof() to get an unqualified type. This works correctly for the compilers, but fails for sparse when the data type is __be64 (or any other __beNN variant). On sparse runs (C=[12]) __beNN types are annotated with __attribute__((bitwise)). That annotation allows sparse to detect incompatible operations on __beNN variables, but it also prevents sparse from evaluating the _Generic() in __unqual_scalar_typeof() and map __beNN to a unqualified scalar type, so it ends up with the default, i.e. the original qualified type of a 'const __beNN' pointer. That then ends up as the first pointer argument to builtin_memcpy(), which obviously causes the above sparse warnings. The sparse git tree supports typeof_unqual() now, which allows to use it instead of the _Generic() based __unqual_scalar_typeof(). With that sparse correctly evaluates the unqualified type and keeps the __beNN logic intact. The downside is that this requires a top of tree sparse build and an old sparse version will emit a metric ton of incomprehensible error messages before it dies with a segfault. Therefore implement a sanity check which validates that the checker is available and capable of handling typeof_unqual(). Emit a warning if not so the user can take informed action. [ tglx: Move the evaluation of USE_TYPEOF_UNQUAL to compiler_types.h so it is set before use and implement the sanity checker ] Reported-by: kernel test robot <lkp@intel.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Closes: https://lore.kernel.org/oe-kbuild-all/202601150001.sKSN644a-lkp@intel.com/ --- Makefile | 8 ++++++++ include/linux/compiler.h | 10 ---------- include/linux/compiler_types.h | 11 +++++++++++ scripts/checker-valid.sh | 19 +++++++++++++++++++ 4 files changed, 38 insertions(+), 10 deletions(-) --- a/Makefile +++ b/Makefile @@ -1178,6 +1178,14 @@ ifdef CONFIG_CC_IS_CLANG KBUILD_USERLDFLAGS += --ld-path=$(LD) endif +# Validate the checker is available and functional +ifneq ($(KBUILD_CHECKSRC), 0) + ifneq ($(shell $(srctree)/scripts/checker-valid.sh $(CHECK)), 1) + $(warning C=$(KBUILD_CHECKSRC) specified, but $(CHECK) is not available or not up to date) + KBUILD_CHECKSRC = 0 + endif +endif + # make the checker run with the right architecture CHECKFLAGS += --arch=$(ARCH) --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -231,16 +231,6 @@ void ftrace_likely_update(struct ftrace_ "must be non-C-string (not NUL-terminated)") /* - * Use __typeof_unqual__() when available. - * - * XXX: Remove test for __CHECKER__ once - * sparse learns about __typeof_unqual__(). - */ -#if CC_HAS_TYPEOF_UNQUAL && !defined(__CHECKER__) -# define USE_TYPEOF_UNQUAL 1 -#endif - -/* * Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof * operator when available, to return an unqualified type of the exp. */ --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -562,6 +562,13 @@ struct ftrace_likely_data { #define asm_inline asm #endif +/* + * Use __typeof_unqual__() when available. + */ +#if CC_HAS_TYPEOF_UNQUAL || defined(__CHECKER__) +# define USE_TYPEOF_UNQUAL 1 +#endif + /* Are two types/vars the same type (ignoring qualifiers)? */ #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) @@ -569,6 +576,7 @@ struct ftrace_likely_data { * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving * non-scalar types unchanged. */ +#ifndef USE_TYPEOF_UNQUAL /* * Prefer C11 _Generic for better compile-times and simpler code. Note: 'char' * is not type-compatible with 'signed char', and we define a separate case. @@ -586,6 +594,9 @@ struct ftrace_likely_data { __scalar_type_to_expr_cases(long), \ __scalar_type_to_expr_cases(long long), \ default: (x))) +#else +#define __unqual_scalar_typeof(x) __typeof_unqual__(x) +#endif /* Is this type a native word size -- useful for atomic operations */ #define __native_word(t) \ --- /dev/null +++ b/scripts/checker-valid.sh @@ -0,0 +1,19 @@ +#!/bin/sh -eu +# SPDX-License-Identifier: GPL-2.0 + +[ ! -x "$(command -v "$1")" ] && exit 1 + +tmp_file=$(mktemp) +trap "rm -f $tmp_file" EXIT + +cat << EOF >$tmp_file +static inline int u(const int *q) +{ + __typeof_unqual__(*q) v = *q; + return v; +} +EOF + +# sparse happily exits with 0 on error so validate +# there is none on stderr. Use awk as grep is a pain with sh -e +$1 $tmp_file 2>&1 | awk -v c=1 '/error/{c=0}END{print c}' ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] compiler: Use __typeof_unqual__() for __unqual_scalar_typeof() 2026-01-16 18:18 ` [PATCH] compiler: Use __typeof_unqual__() for __unqual_scalar_typeof() Thomas Gleixner @ 2026-01-17 5:25 ` Ian Rogers 2026-02-25 8:15 ` Dan Carpenter 1 sibling, 0 replies; 11+ messages in thread From: Ian Rogers @ 2026-01-17 5:25 UTC (permalink / raw) To: Thomas Gleixner Cc: Peter Zijlstra, kernel test robot, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Fri, Jan 16, 2026 at 10:18 AM Thomas Gleixner <tglx@kernel.org> wrote: > > From: Peter Zijlstra <peterz@infradead.org> > > The recent changes to get_unaligned() resulted in a new sparse warning: > > net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) @@ expected void * @@ got restricted __be64 const * @@ > net/rds/ib_cm.c:96:35: sparse: expected void * > net/rds/ib_cm.c:96:35: sparse: got restricted __be64 const * > > The updated get_unaligned_t() uses __unqual_scalar_typeof() to get an > unqualified type. This works correctly for the compilers, but fails for > sparse when the data type is __be64 (or any other __beNN variant). > > On sparse runs (C=[12]) __beNN types are annotated with > __attribute__((bitwise)). > > That annotation allows sparse to detect incompatible operations on __beNN > variables, but it also prevents sparse from evaluating the _Generic() in > __unqual_scalar_typeof() and map __beNN to a unqualified scalar type, so it > ends up with the default, i.e. the original qualified type of a 'const > __beNN' pointer. That then ends up as the first pointer argument to > builtin_memcpy(), which obviously causes the above sparse warnings. > > The sparse git tree supports typeof_unqual() now, which allows to use it > instead of the _Generic() based __unqual_scalar_typeof(). With that sparse > correctly evaluates the unqualified type and keeps the __beNN logic intact. Wow, that's painful. Congratulations on finding the root case. Acked-by: Ian Rogers <irogers@google.com> Thanks, Ian > The downside is that this requires a top of tree sparse build and an old > sparse version will emit a metric ton of incomprehensible error messages > before it dies with a segfault. > > Therefore implement a sanity check which validates that the checker is > available and capable of handling typeof_unqual(). Emit a warning if not so > the user can take informed action. > > [ tglx: Move the evaluation of USE_TYPEOF_UNQUAL to compiler_types.h so it is > set before use and implement the sanity checker ] > > Reported-by: kernel test robot <lkp@intel.com> > Signed-off-by: Peter Zijlstra <peterz@infradead.org> > Signed-off-by: Thomas Gleixner <tglx@kernel.org> > Closes: https://lore.kernel.org/oe-kbuild-all/202601150001.sKSN644a-lkp@intel.com/ > --- > Makefile | 8 ++++++++ > include/linux/compiler.h | 10 ---------- > include/linux/compiler_types.h | 11 +++++++++++ > scripts/checker-valid.sh | 19 +++++++++++++++++++ > 4 files changed, 38 insertions(+), 10 deletions(-) > > --- a/Makefile > +++ b/Makefile > @@ -1178,6 +1178,14 @@ ifdef CONFIG_CC_IS_CLANG > KBUILD_USERLDFLAGS += --ld-path=$(LD) > endif > > +# Validate the checker is available and functional > +ifneq ($(KBUILD_CHECKSRC), 0) > + ifneq ($(shell $(srctree)/scripts/checker-valid.sh $(CHECK)), 1) > + $(warning C=$(KBUILD_CHECKSRC) specified, but $(CHECK) is not available or not up to date) > + KBUILD_CHECKSRC = 0 > + endif > +endif > + > # make the checker run with the right architecture > CHECKFLAGS += --arch=$(ARCH) > > --- a/include/linux/compiler.h > +++ b/include/linux/compiler.h > @@ -231,16 +231,6 @@ void ftrace_likely_update(struct ftrace_ > "must be non-C-string (not NUL-terminated)") > > /* > - * Use __typeof_unqual__() when available. > - * > - * XXX: Remove test for __CHECKER__ once > - * sparse learns about __typeof_unqual__(). > - */ > -#if CC_HAS_TYPEOF_UNQUAL && !defined(__CHECKER__) > -# define USE_TYPEOF_UNQUAL 1 > -#endif > - > -/* > * Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof > * operator when available, to return an unqualified type of the exp. > */ > --- a/include/linux/compiler_types.h > +++ b/include/linux/compiler_types.h > @@ -562,6 +562,13 @@ struct ftrace_likely_data { > #define asm_inline asm > #endif > > +/* > + * Use __typeof_unqual__() when available. > + */ > +#if CC_HAS_TYPEOF_UNQUAL || defined(__CHECKER__) > +# define USE_TYPEOF_UNQUAL 1 > +#endif > + > /* Are two types/vars the same type (ignoring qualifiers)? */ > #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) > > @@ -569,6 +576,7 @@ struct ftrace_likely_data { > * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving > * non-scalar types unchanged. > */ > +#ifndef USE_TYPEOF_UNQUAL > /* > * Prefer C11 _Generic for better compile-times and simpler code. Note: 'char' > * is not type-compatible with 'signed char', and we define a separate case. > @@ -586,6 +594,9 @@ struct ftrace_likely_data { > __scalar_type_to_expr_cases(long), \ > __scalar_type_to_expr_cases(long long), \ > default: (x))) > +#else > +#define __unqual_scalar_typeof(x) __typeof_unqual__(x) > +#endif > > /* Is this type a native word size -- useful for atomic operations */ > #define __native_word(t) \ > --- /dev/null > +++ b/scripts/checker-valid.sh > @@ -0,0 +1,19 @@ > +#!/bin/sh -eu > +# SPDX-License-Identifier: GPL-2.0 > + > +[ ! -x "$(command -v "$1")" ] && exit 1 > + > +tmp_file=$(mktemp) > +trap "rm -f $tmp_file" EXIT > + > +cat << EOF >$tmp_file > +static inline int u(const int *q) > +{ > + __typeof_unqual__(*q) v = *q; > + return v; > +} > +EOF > + > +# sparse happily exits with 0 on error so validate > +# there is none on stderr. Use awk as grep is a pain with sh -e > +$1 $tmp_file 2>&1 | awk -v c=1 '/error/{c=0}END{print c}' ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] compiler: Use __typeof_unqual__() for __unqual_scalar_typeof() 2026-01-16 18:18 ` [PATCH] compiler: Use __typeof_unqual__() for __unqual_scalar_typeof() Thomas Gleixner 2026-01-17 5:25 ` Ian Rogers @ 2026-02-25 8:15 ` Dan Carpenter 1 sibling, 0 replies; 11+ messages in thread From: Dan Carpenter @ 2026-02-25 8:15 UTC (permalink / raw) To: Thomas Gleixner Cc: Peter Zijlstra, kernel test robot, Ian Rogers, oe-kbuild-all, linux-kernel, x86, sparse, linux-sparse, Marco Elver On Fri, Jan 16, 2026 at 07:18:16PM +0100, Thomas Gleixner wrote: > --- a/Makefile > +++ b/Makefile > @@ -1178,6 +1178,14 @@ ifdef CONFIG_CC_IS_CLANG > KBUILD_USERLDFLAGS += --ld-path=$(LD) > endif > > +# Validate the checker is available and functional > +ifneq ($(KBUILD_CHECKSRC), 0) > + ifneq ($(shell $(srctree)/scripts/checker-valid.sh $(CHECK)), 1) > + $(warning C=$(KBUILD_CHECKSRC) specified, but $(CHECK) is not available or not up to date) > + KBUILD_CHECKSRC = 0 > + endif > +endif > + This means we can't run "CHECK="valgrind smatch -p=kernel" because valgrind always prints output to stderr. So hopefully we can eventually remove this check. regards, dan carpenter ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-02-25 8:15 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <202601150001.sKSN644a-lkp@intel.com>
2026-01-15 19:28 ` [tip:timers/vdso 12/14] net/rds/ib_cm.c:96:35: sparse: sparse: incorrect type in argument 1 (different modifiers) Thomas Gleixner
2026-01-15 21:11 ` Peter Zijlstra
2026-01-15 21:19 ` Linus Torvalds
2026-01-15 21:30 ` Peter Zijlstra
2026-01-15 23:03 ` Linus Torvalds
2026-01-16 8:28 ` Peter Zijlstra
2026-01-15 23:01 ` Thomas Gleixner
2026-01-16 11:25 ` Thomas Gleixner
2026-01-16 18:18 ` [PATCH] compiler: Use __typeof_unqual__() for __unqual_scalar_typeof() Thomas Gleixner
2026-01-17 5:25 ` Ian Rogers
2026-02-25 8:15 ` Dan Carpenter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox