Re: [peterz-queue:x86/wip.extable 1/22] drivers/crypto/ccree/cc_driver.c:117:18: warning: result of comparison of constant 18446744073709551615 with expression of type 'typeof (_Generic((mask), char: (unsigned char)0, unsigned char: (unsigned char)0, signed char: (unsigned char)0, unsigned shor...

From: Peter Zijlstra
Date: Fri Nov 05 2021 - 20:35:50 EST


On Fri, Nov 05, 2021 at 02:06:22PM -0700, Nick Desaulniers wrote:
> On Fri, Nov 5, 2021 at 5:21 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:

> > I'm confused here.. the code reads:
> >
> >
> > #define __scalar_type_to_unsigned_cases(type) \
> > unsigned type: (unsigned type)0, \
> > signed type: (unsigned type)0
> >
> > #define __unsigned_scalar_typeof(x) typeof( \
> > _Generic((x), \
> > char: (unsigned char)0, \
> > __scalar_type_to_unsigned_cases(char), \
> > __scalar_type_to_unsigned_cases(short), \
> > __scalar_type_to_unsigned_cases(int), \
> > __scalar_type_to_unsigned_cases(long), \
> > __scalar_type_to_unsigned_cases(long long), \
> > default: (x)))
> >
> > #define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x))
> >
> > #define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
> > ({ \
> > BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
> > _pfx "mask is not constant"); \
> > BUILD_BUG_ON_MSG((_mask) == 0, _pfx "mask is zero"); \
> > BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \
> > ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
> > _pfx "value too large for the field"); \
> > BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
> > __bf_cast_unsigned(_reg, ~0ull), \
> > _pfx "type of reg too small for mask"); \
> > __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
> > (1ULL << __bf_shf(_mask))); \
> > })
> >
> > #define FIELD_PREP(_mask, _val) \
> > ({ \
> > __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
> > ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
> > })
> >
> >
> > static void init_cc_cache_params(struct cc_drvdata *drvdata)
> > {
> > struct device *dev = drvdata_to_dev(drvdata);
> > u32 cache_params, ace_const, val, mask;
> >
> > ...
> >
> > mask = CC_GENMASK(CC_AXIM_CACHE_PARAMS_AWCACHE); <-- *BOOM*
> > cache_params &= ~mask;
> > cache_params |= FIELD_PREP(mask, val);
> >
> > ...
> > }
> >
> > So we're having "(unsigned int)mask > (unsigned long long)~0ull" as
> > a compile time constant input to the BUILD_BUG_ON_MSG(), and clang-14 is
> > now complaining it's a constant ?!?
>
> No, the error message (trimmed for clarity):
> >> warning: result of comparison of constant 18446744073709551615 (ie ~0ull / ULLONG_MAX) with expression of type ... 'unsigned int') is always false [-Wtautological-constant-out-of-range-compare]
>
> Is `val` an int, but should be a long long? We're comparing if an
> unsigned int is greater than ULLONG_MAX, which is impossible (or
> rather a tautology; something that's always either true or false, in
> this case false). Or maybe mask and reg are different widths?

They are, for FIELD_PREP() as is the case here, _mask is u32 while _reg
is typeof(0ULL). In my reading of the code this is on purpose to
basically disable the test for this caller.