Details

When generating initializers for local structures in the -ftrivial-auto-var-init mode, explicitly wipe the padding bytes with either 0x00 or 0xAA.
This will allow us to automatically handle the padding when splitting the initialization stores (see https://reviews.llvm.org/D57898).

I think eventually we want to put this behind a flag, off by default, just like auto-init. Auto-init should imply padding init for stack values. In a way you're doing the later part, but I think you want to initialize (and test) not just stack values. You want every padding bit to be blown away, whether it's on the heap or on the stack. Of course for heap values, when uninitialized, the padding is also uninitialized (unless you're doing auto-init).

Maybe this narrow patch is a good start, and the rest can be handled later? For example, this seems to handle union *initialization* correctly (says your @__const.test_unmatchedreverse_custom.custom update), but it won't handle union *assignments* correctly when we want to avoid padding leaks. Say I have this:

We want to handle padding comprehensively, not just initialization. Here you want to blow away whatever was in u.i when assigning to u.c, that way reads of u.i as well as any memcpy or just random reads don't leak what was there before.

You'll want to add tests which use __attribute__((aligned(X)) in weird places.

It seems like some of this can be factored out to its own function. I'm a bit worried that real-world code will end up spending some amount of time in here, once the patch is further along it might be useful to compile LLVM with itself, and see if there's a compile-time hit. If so, it might be worth memoizing some stuff.

We want to handle padding comprehensively, not just initialization. Here you want to blow away whatever was in u.i when assigning to u.c, that way reads of u.i as well as any memcpy or just random reads don't leak what was there before.

Wonder if the kernel doesn't contain code that relies on both union fields being available at the same time.

We want to handle padding comprehensively, not just initialization. Here you want to blow away whatever was in u.i when assigning to u.c, that way reads of u.i as well as any memcpy or just random reads don't leak what was there before.

Wonder if the kernel doesn't contain code that relies on both union fields being available at the same time.

Yes, because it wasn't being always initialized before. It was up to the backend to decide whether to synthesize a value into padding or not. Now we're always putting a value in there.

That being said, we could put something else that 0xAA if we know adjacent things are being initialized. Sometimes that'll codegen better. That's what I did in patternFor when there's undef: I pick an adjacent byte value, so we might be lucky and get something that's easier to synthesize as an immediate.

Ok, since the standard actually doesn't mandate the padding byte values, we can make them pattern bytes for now just for the sake of consistency.
If at some point we find out that this costs us performance, we can always change this behavior.