So what will happen if I do base = derived;
in clang?
It's the first option. If Base has any padding, the Derived type will include it's padding members too. Same reason as before - because in array of Base types each element must be aligned properly.
But it doesn't matter when I have an array of the derived type, right? Why does the derived must include padding? And why doesn't clang choose those benefits?
It will work fine in this case.
It won't work fine if you have virtual methods - because that means "slicing" of data will happen - overriden virtual methods will still be called from Derived class, but only fields of Base class will be present.
But it doesn't matter when I have an array of the derived type, right? Why does the derived must include padding? And why doesn't clang choose those benefits?
That's just some internal decision in compiler. Some compiler prefers to assume all types can go into array, so to simplify layout they just add padding. Clang tries to be smarter this way and avoids that. It's just part of optimization.