Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
From: David Laight
Date: Wed Jan 21 2026 - 16:05:53 EST
On Wed, 21 Jan 2026 19:43:07 +0100
Vincent Mailhol <mailhol@xxxxxxxxxx> wrote:
> On 21/01/2026 at 15:57, david.laight.linux@xxxxxxxxx wrote:
> > From: David Laight <david.laight.linux@xxxxxxxxx>
> >
> > The current checks in GENMASK/BIT (eg reversed high/low) only work
> > for 'integer constant expressions' not 'compile-time constants'.
> > This is true for const_true() and -Wshift-count-overflow/negative.
> > While compile-time constants may be unusual, they can happen through
> > function inlining.
>
> Did those new checks actually found any real problem in the code? This
> adds a lot of complexity so I am not sure whether this is a winning
> trade-off.
Not in an x86-64 allmodconfig build.
They might in a 32bit one where there have definitely been issues.
>
> > This isn't too bad with gcc, but if clang detects a negative/over-large
> > shift it treats it as 'undefined behaviour' and silently discards all
> > code that would use the result, so:
> > int f(u32 x) {int n = 32; return x >> n; }
> > generates a function that just contains a 'return' instruction.
> > If 'n' was a variable that happened to be 32, most modern cpu mask
> > the count - so would return 'x', some might return 0.
>
> But then, you only solve that shift problem for GENMASK() and
> BIT(). Any other usage of the left/right shifts are not diagnosed
> unless your check get copy pasted all over the place.
>
> I think that such a check belongs to a static analyzer. Speaking of
> which:
>
> $ cat test.c
> typedef unsigned int u32;
> static int f(u32 x) {int n = 32; return x >> n; }
>
> $ sparse test.c
> test.c:2:46: warning: shift too big (32) for type unsigned int$ cat test.c
>
> So here, I would rather keep relying on sparse rather that introducing
> the W=c logic and all that macro complexity.
I suspect the compiler test will find more than sparse.
I liked getting that to work, but maybe it is OTT.
But the W=c is more generally useful.
As well as removing all the compile-time tests from GENMASK() and
(in another patch FIELD_PREP()) which really do bloat the .i file,
I'd like to add some new tests to min/max/clamp to try to get rid
of the more dodgy (and likely buggy) cases without breaking
everyone's build - just failing the W=1 builds is better.
Using a separate flag means you can use W=ce to stop the build,
doing a W=1e build is hopeless.
David
>
>
> Yours sincerely,
> Vincent Mailhol