Peter Zijlstra
2022-Apr-14 15:21 UTC
[PATCH 1/3] sched/headers: Fix compilation error with GCC 12
On Thu, Apr 14, 2022 at 05:08:53PM +0200, Christophe de Dinechin wrote:> With gcc version 12.0.1 20220401 (Red Hat 12.0.1-0) (GCC), the following > errors are reported in sched.h when building after `make defconfig`:<snip tons of noise>> Rewrite the definitions of sched_class_highest and for_class_range to > avoid this error as follows: > > 1/ The sched_class_highest is rewritten to be relative to > __begin_sched_classes, so that GCC sees it as being part of the > __begin_sched_classes array and not a distinct __end_sched_classes > array. > > 2/ The for_class_range macro is modified to replace the comparison with > an out-of-bound pointer __begin_sched_classes - 1 with an equivalent, > but in-bounds comparison. > > In that specific case, I believe that the GCC analysis is correct and > potentially valuable for other arrays, so it makes sense to keep it > enabled. > > Signed-off-by: Christophe de Dinechin <christophe at dinechin.org> > Signed-off-by: Christophe de Dinechin <dinechin at redhat.com> > --- > kernel/sched/sched.h | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h > index 8dccb34eb190..6350fbc7418d 100644 > --- a/kernel/sched/sched.h > +++ b/kernel/sched/sched.h > @@ -2193,11 +2193,18 @@ const struct sched_class name##_sched_class \ > extern struct sched_class __begin_sched_classes[]; > extern struct sched_class __end_sched_classes[]; > > -#define sched_class_highest (__end_sched_classes - 1) > +/* > + * sched_class_highests is really __end_sched_classes - 1, but written in a way > + * that makes it clear that it is within __begin_sched_classes[] and not outside > + * of __end_sched_classes[]. > + */ > +#define sched_class_highest (__begin_sched_classes + \ > + (__end_sched_classes - __begin_sched_classes - 1)) > #define sched_class_lowest (__begin_sched_classes - 1) > > +/* The + 1 below places the pointers within the range of their array */ > #define for_class_range(class, _from, _to) \ > - for (class = (_from); class != (_to); class--) > + for (class = (_from); class + 1 != (_to) + 1; class--)Urgh, so now we get less readable code, just because GCC is being stupid? What's wrong with negative array indexes? memory is memory, stuff works.
Andrew Morton
2022-Apr-14 20:30 UTC
[PATCH 1/3] sched/headers: Fix compilation error with GCC 12
On Thu, 14 Apr 2022 17:21:01 +0200 Peter Zijlstra <peterz at infradead.org> wrote:> > +/* The + 1 below places the pointers within the range of their array */ > > #define for_class_range(class, _from, _to) \ > > - for (class = (_from); class != (_to); class--) > > + for (class = (_from); class + 1 != (_to) + 1; class--) > > Urgh, so now we get less readable code, just because GCC is being > stupid? > > What's wrong with negative array indexes? memory is memory, stuff works.What's more, C is C. Glorified assembly language in which people do odd stuff. But this is presumably a released gcc version and we need to do something. And presumably, we need to do a backportable something, so people can compile older kernels with gcc-12. Is it possible to suppress just this warning with a gcc option? And if so, are we confident that this warning will never be useful in other places in the kernel? If no||no then we'll need to add workarounds such as these?
David Laight
2022-Apr-17 13:27 UTC
[PATCH 1/3] sched/headers: Fix compilation error with GCC 12
From: Peter Zijlstra> Sent: 14 April 2022 16:21...> <snip tons of noise> >..> > -#define sched_class_highest (__end_sched_classes - 1) > > +/* > > + * sched_class_highests is really __end_sched_classes - 1, but written in a way > > + * that makes it clear that it is within __begin_sched_classes[] and not outside > > + * of __end_sched_classes[]. > > + */ > > +#define sched_class_highest (__begin_sched_classes + \ > > + (__end_sched_classes - __begin_sched_classes - 1)) > > #define sched_class_lowest (__begin_sched_classes - 1) > > > > +/* The + 1 below places the pointers within the range of their array */ > > #define for_class_range(class, _from, _to) \ > > - for (class = (_from); class != (_to); class--) > > + for (class = (_from); class + 1 != (_to) + 1; class--)That is still technically broken because you are still calculating the address of array[-1] - even though it is probably optimised out.> Urgh, so now we get less readable code, just because GCC is being > stupid? > > What's wrong with negative array indexes? memory is memory, stuff works.Consider segmented x86 where malloc() always returns {segment:0..segment:size). Pointer arithmetic will only change the offset. So &array[-1] is likely to be greater than &array[0]. So it has never been valid C to create pointers to before a data item. OTOH I've NFI why gcc and clang have started generating warnings for portability issues that really don't affect mainstream systems. I'm just waiting for them to warn about memset(p, 0 sizeof *p) when the structure contains pointers - because the NULL pointer doesn't have to be the all-zero bit pattern. The only reason (int)&(struct foo *)0->member is non-portable is because NULL might not be 0. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)