Re: arm32 build warnings in workqueue.c

From: Tejun Heo
Date: Fri Jun 23 2023 - 21:33:09 EST


Hello, Linus.

On Fri, Jun 23, 2023 at 03:15:51PM -0700, Linus Torvalds wrote:
> On Fri, 23 Jun 2023 at 12:48, Tejun Heo <tj@xxxxxxxxxx> wrote:
> > The behavior change in gcc-13 is fine on its own but it's frustrating
> > because there's no way to obtain previous behavior
>
> No, the previous gcc behavior was just buggy and wrong.
>
> I'm actually surprised at what gcc did. It means that each enum, has a
> different type. That's just completely wrong, and means that there is
> no such thing as a proper enum type.

I agree that the previous behavior is out there. It's just that it's been
like that forever and that's been the only way to make constants externally
visible.

> And the types are entirely random. They are *not* the types of the
> initializers. Try this:
>
> enum {
> A = (char) 1,
> B = (unsigned long) 2,
> C = (long long) 3,
> D = (unsigned long) 0x123456789,
> };
>
> int tA(void) { return sizeof(A); }
> int tB(void) { return sizeof(B); }
> int tC(void) { return sizeof(C); }
> int tD(void) { return sizeof(D); }
> int T(void) { return sizeof(enum bad); }
> int crazy(void) { return sizeof(typeof(A)); }
>
> and look at the insanity when you compile it with "gcc -S".

Oh yeah, the sizes make no senes.

> So no. There is NO WAY we want to ever "obtain previous behavior".
> That is just garbage. Any code that depends on that behavior is just
> actively wrong.

Nothing is willingly depending on the crazy type behavior. However, enums
are the only thing we've got if we want to make the constant values visible
externally, so we have to make do with them somehow. It has always been iffy
but also mostly bearable. Recent round of problems stem from the fact that
gcc-13 changed the behavior and it sometimes gets nasty to satisfy both
interpretations with the same code. Hypothetically, if we were to declare
that we no longer supported old craziness, cleaning things up would be
straight-forward.

That day will come in the future but, in the meantime, we have to deal with
enums whose sizes are going to be different depending on the complier
version. It's pretty unpleasant but likely manageable in practice. The only
way I can think of to keep the before and after behaviors the same is
defining every enum in its own enum block. ie. Explicitly force each to be
its own type. With a macro helper, code would probably look okay and we'd be
explicitly telling the compiler to pick the type that can contain the value
while maintaining signedness. That would give us consistent behaviors across
the gcc-12/13 boundary. It sure doesn't feel great tho.

Unless we declare that we don't care about external visibility and are done
with enums, none of the available options aren't great, which isn't too
surprising given the sad state enums have been in.

Thanks.

--
tejun