W=2 builds are heavily polluted by the -Wtype-limits warning.
Here are some W=12 statistics on Linux v6.19-rc1 for an x86_64
defconfig (with just CONFIG_WERROR set to "n") using gcc 14.3.1:
Warning name count percent
-------------------------------------------------
-Wlogical-op 2 0.00 %
-Wmaybe-uninitialized 138 0.20 %
-Wunused-macros 869 1.24 %
-Wmissing-field-initializers 1418 2.02 %
-Wshadow 2234 3.19 %
-Wtype-limits 65378 93.35 %
-------------------------------------------------
Total 70039 100.00 %
As we can see, -Wtype-limits represents the vast majority of all
warnings. The reason behind this is that these warnings appear in
some common header files, meaning that some unique warnings are
repeated tens of thousands of times (once per header inclusion).
Add to this the fact that each warning is coupled with a dozen lines
detailing some macro expansion. The end result is that the W=2 output
is just too bloated and painful to use.
Three years ago, I proposed in [1] modifying one such header to
silence that noise. Because the code was not faulty, Linus rejected
the idea and instead suggested simply removing that warning.
At that time, I could not bring myself to send such a patch because,
despite its problems, -Wtype-limits would still catch the below bug:
unsigned int ret;
ret = check();
if (ret < 0)
error();
Meanwhile, based on another suggestion from Linus, I added a new check
to sparse [2] that would catch the above bug without the useless spam.
With this, remove gcc's -Wtype-limits. People who still want to catch
incorrect comparisons between unsigned integers and zero can now use
sparse instead.
On a side note, clang also has a -Wtype-limits warning but:
* it is not enabled in the kernel at the moment because, contrary to
gcc, clang did not include it under -Wextra.
* it does not warn if the code results from a macro expansion. So,
if activated, it would not cause as much spam as gcc does.
* -Wtype-limits is split into four sub-warnings [3] meaning that if
it were to be activated, we could select which one to keep.
So there is no present need to explicitly disable -Wtype-limits in
clang.
[1] linux/bits.h: GENMASK_INPUT_CHECK: reduce W=2 noise by 31% treewide
Link: https://lore.kernel.org/all/20220308141201.2343757-1-mailhol.vincent@wanadoo.fr/
[2] Warn about "unsigned value that used to be signed against zero"
Link: https://lore.kernel.org/all/20250921061337.3047616-1-mailhol@kernel.org/
[3] clang's -Wtype-limits
Link: https://clang.llvm.org/docs/DiagnosticsReference.html#wtype-limits
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
---
scripts/Makefile.warn | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scripts/Makefile.warn b/scripts/Makefile.warn
index 68e6fafcb80c..c593ab1257de 100644
--- a/scripts/Makefile.warn
+++ b/scripts/Makefile.warn
@@ -55,6 +55,9 @@ else
KBUILD_CFLAGS += -Wno-main
endif
+# Too noisy on range checks and in macros handling both signed and unsigned.
+KBUILD_CFLAGS += -Wno-type-limits
+
# These result in bogus false positives
KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer)
@@ -174,7 +177,6 @@ else
# The following turn off the warnings enabled by -Wextra
KBUILD_CFLAGS += -Wno-missing-field-initializers
-KBUILD_CFLAGS += -Wno-type-limits
KBUILD_CFLAGS += -Wno-shift-negative-value
ifdef CONFIG_CC_IS_CLANG
--
2.51.2
On Thu, Dec 18, 2025 at 07:50:01PM +0100, Vincent Mailhol wrote: > W=2 builds are heavily polluted by the -Wtype-limits warning. > > Here are some W=12 statistics on Linux v6.19-rc1 for an x86_64 > defconfig (with just CONFIG_WERROR set to "n") using gcc 14.3.1: > > Warning name count percent > ------------------------------------------------- > -Wlogical-op 2 0.00 % > -Wmaybe-uninitialized 138 0.20 % > -Wunused-macros 869 1.24 % > -Wmissing-field-initializers 1418 2.02 % > -Wshadow 2234 3.19 % > -Wtype-limits 65378 93.35 % > ------------------------------------------------- > Total 70039 100.00 % > > As we can see, -Wtype-limits represents the vast majority of all > warnings. The reason behind this is that these warnings appear in > some common header files, meaning that some unique warnings are > repeated tens of thousands of times (once per header inclusion). > > Add to this the fact that each warning is coupled with a dozen lines > detailing some macro expansion. The end result is that the W=2 output > is just too bloated and painful to use. > > Three years ago, I proposed in [1] modifying one such header to > silence that noise. Because the code was not faulty, Linus rejected > the idea and instead suggested simply removing that warning. > > At that time, I could not bring myself to send such a patch because, > despite its problems, -Wtype-limits would still catch the below bug: > > unsigned int ret; > > ret = check(); > if (ret < 0) > error(); > > Meanwhile, based on another suggestion from Linus, I added a new check > to sparse [2] that would catch the above bug without the useless spam. > > With this, remove gcc's -Wtype-limits. People who still want to catch > incorrect comparisons between unsigned integers and zero can now use > sparse instead. > > On a side note, clang also has a -Wtype-limits warning but: > > * it is not enabled in the kernel at the moment because, contrary to > gcc, clang did not include it under -Wextra. > > * it does not warn if the code results from a macro expansion. So, > if activated, it would not cause as much spam as gcc does. > > * -Wtype-limits is split into four sub-warnings [3] meaning that if > it were to be activated, we could select which one to keep. > Sounds good. I like your Sparse check. Maybe we should enable the Sparse checking as well because it sounds like they are doing a lot of things right. I think Smatch catches the same bugs that Clang would but it would be good to have multiple implementations. The -Wtautological-unsigned-enum-zero-compare trips people up because they aren't necessarily expecting enums to be unsigned. regards, dan carpenter
Hi Dan,
On 18/12/2025 at 20:36, Dan Carpenter wrote:
> On Thu, Dec 18, 2025 at 07:50:01PM +0100, Vincent Mailhol wrote:
(...)
>> With this, remove gcc's -Wtype-limits. People who still want to catch
>> incorrect comparisons between unsigned integers and zero can now use
>> sparse instead.
>>
>> On a side note, clang also has a -Wtype-limits warning but:
>>
>> * it is not enabled in the kernel at the moment because, contrary to
>> gcc, clang did not include it under -Wextra.
>>
>> * it does not warn if the code results from a macro expansion. So,
>> if activated, it would not cause as much spam as gcc does.
>>
>> * -Wtype-limits is split into four sub-warnings [3] meaning that if
>> it were to be activated, we could select which one to keep.
>>
>
> Sounds good. I like your Sparse check.
Does it mean I have your Reviewed-by?
> Maybe we should enable the Sparse checking as well because it sounds
> like they are doing a lot of things right.
I am not sure to understand what do you mean by "enable the Sparse checking"?
The new sparse check I introduced is on by default.
> I think Smatch catches the
> same bugs that Clang would but it would be good to have multiple
> implementations. The -Wtautological-unsigned-enum-zero-compare trips
> people up because they aren't necessarily expecting enums to be
> unsigned.
I do not know enough about Smatch, I will let you judge on that one.
Concerning clang, here are the statistics:
$ make -s LLVM=1 CFLAGS_KERNEL="-Wtype-limits" 2>&1 | grep -o '\[-W\S*\]' | sort | uniq -c
2 [-Wtautological-type-limit-compare]
15 [-Wtautological-unsigned-enum-zero-compare]$ make -s LLVM=1 CFLAGS_KERNEL="-Wtype-limits"
(done on a linux v6.19-rc1 defconfig with clang v20.1.8)
Not so many warnings, at least, less than what I would have thought!
-Wtautological-unsigned-char-zero-compare and
-Wtautological-unsigned-zero-compare gave zero findings. So those two
can be enabled, I guess? I am still surprised that
-Wtautological-unsigned-zero-compare gives nothing. I would have
expected some kind of false positives on that one. No sure if I missed
something here.
The two -Wtautological-type-limit-compare are:
fs/libfs.c:1640:20: warning: result of comparison 'u64' (aka 'unsigned long long') > 18446744073709551615 is always false [-Wtautological-type-limit-compare]
1640 | (last_fs_page > (pgoff_t)(~0ULL))) {
| ~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~
1 warning generated.
block/ioctl.c:765:29: warning: result of comparison 'sector_t' (aka 'unsigned long long') > 18446744073709551615 is always false [-Wtautological-type-limit-compare]
765 | if (bdev_nr_sectors(bdev) > ~0UL)
| ~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
1 warning generated.
If I got it correctly, those checks are just meant for the case where
unsigned long are 32 bits.
Because clang does not warn when the code comes from a macro
expansion, a way to silent these would be to use:
(last_fs_page > type_max(pgoff_t))
in fs/libfs.c and:
if (bdev_nr_sectors(bdev) > ULONG_MAX)
in block/ioctl.c.
Well, none of those findings were incorrect to begin with, but
arguably, the code readability can be improved.
So, I would say why not for -Wtautological-type-limit-compare.
Concerning the -Wtautological-unsigned-enum-zero-compare, here is a
representative finding:
drivers/video/hdmi.c:1099:20: warning: result of comparison of unsigned enum expression < 0 is always false [-Wtautological-unsigned-enum-zero-compare]
1099 | if (active_aspect < 0 || active_aspect > 0xf)
| ~~~~~~~~~~~~~ ^ ~
(all the other 14 findings follow the same pattern).
Here, the code just want to check that a value is in range. This is
the same logic as gcc's -Wtype-limits: something we do *not* want.
So -Wtautological-unsigned-enum-zero-compare will stay disabled.
In conclusion, I agree that we could enable three of clang's
-Wtype-limits sub-warning. But this is not the scope of that series. I
would rather prefer to have this as a separate series.
Yours sincerely,
Vincent Mailhol
On 18/12/2025 at 23:31, Vincent Mailhol wrote: (...) > Concerning clang, here are the statistics: > > $ make -s LLVM=1 CFLAGS_KERNEL="-Wtype-limits" 2>&1 | grep -o '\[-W\S*\]' | sort | uniq -c > 2 [-Wtautological-type-limit-compare] > 15 [-Wtautological-unsigned-enum-zero-compare]$ make -s LLVM=1 CFLAGS_KERNEL="-Wtype-limits" > > (done on a linux v6.19-rc1 defconfig with clang v20.1.8) > > Not so many warnings, at least, less than what I would have thought! > > -Wtautological-unsigned-char-zero-compare and > -Wtautological-unsigned-zero-compare gave zero findings. So those two > can be enabled, I guess? I am still surprised that > -Wtautological-unsigned-zero-compare gives nothing. I would have > expected some kind of false positives on that one. No sure if I missed > something here. I was a bit worried of that -Wtautological-unsigned-zero-compare got zero findings so I reran a build but this time on an allyesconfig (minus CONFIG_WERROR): $ make -j8 -s LLVM=1 CFLAGS_KERNEL="-Wtype-limits" 2>&1 | grep -o '\[-W\S*\]' | sort | uniq -c 29 [-Wtautological-type-limit-compare] 55 [-Wtautological-unsigned-enum-zero-compare] 76 [-Wtautological-unsigned-zero-compare] This is closer than expected. And looking at the findings, -Wtautological-unsigned-zero-compare also warns on some sane code which is just doing some range checks. (...) > In conclusion, I agree that we could enable three of clang's > -Wtype-limits sub-warning. But this is not the scope of that series. I > would rather prefer to have this as a separate series. With this, I want to amend my conclusion. both -Wtautological-unsigned-enum-zero-compare and -Wtautological-unsigned-zero-compare should be kept disabled. The only candidates are -Wtautological-type-limit-compare and -Wtautological-unsigned-char-zero-compare. -Wtautological-unsigned-char-zero-compare would need another study. It seems that this warning is only triggered on platforms where char is unsigned which explains why I did not see it when building on x86_64. Well, I think I will stop this clang's -Wtype-limits study for the moment. If anyone wants to continue the work please go ahead. Yours sincerely, Vincent Mailhol
On Thu, Dec 18, 2025 at 11:31:40PM +0100, Vincent Mailhol wrote: > Hi Dan, > > On 18/12/2025 at 20:36, Dan Carpenter wrote: > > On Thu, Dec 18, 2025 at 07:50:01PM +0100, Vincent Mailhol wrote: > > (...) > > >> With this, remove gcc's -Wtype-limits. People who still want to catch > >> incorrect comparisons between unsigned integers and zero can now use > >> sparse instead. > >> > >> On a side note, clang also has a -Wtype-limits warning but: > >> > >> * it is not enabled in the kernel at the moment because, contrary to > >> gcc, clang did not include it under -Wextra. > >> > >> * it does not warn if the code results from a macro expansion. So, > >> if activated, it would not cause as much spam as gcc does. > >> > >> * -Wtype-limits is split into four sub-warnings [3] meaning that if > >> it were to be activated, we could select which one to keep. > >> > > > > Sounds good. I like your Sparse check. > > Does it mean I have your Reviewed-by? > > > Maybe we should enable the Sparse checking as well because it sounds > > like they are doing a lot of things right. > > I am not sure to understand what do you mean by "enable the Sparse checking"? I meant Clang... Sorry. Doh. regards, dan carpenter
© 2016 - 2026 Red Hat, Inc.