On 9/28/24 2:39 AM, Jakub Jelinek wrote:
On Fri, Sep 27, 2024 at 04:01:33PM +0200, Jakub Jelinek wrote:
So, I think we should go with (but so far completely untested except
for pr78687.C which is optimized with Marek's patch and the above testcase
which doesn't have the clearing anymore) the following patch.
That patch had a bug in type_has_padding_at_level_p and so it didn't
bootstrap.
Here is a full patch which does. It regressed the infoleak-1.c test
which I've adjusted, but I think the test had undefined behavior.
In particular the question is whether
union un_b { unsigned char j; unsigned int i; } u = {0};
leaves (or can leave) some bits uninitialized or not.
I believe it can, it is an explicit initialization of the j member
which is just 8-bit (but see my upcoming mail on padding bits in C23/C++)
and nothing in the C standard from what I can see seems to imply the padding
bits in the union beyond the actually initialized field in this case would
be initialized.
Agreed, the padding bits have indeterminate values (or erroneous in
C++26), so it's correct for infoleak-1.c to complain about 4b.
Though, looking at godbolt, clang and icc 19 and older gcc all do zero
initialize the whole union before storing the single member in there (if
non-zero, otherwise just clear).
So whether we want to do this or do it by default is another question.
We will want to initialize the padding (for all types) to something for
C++26, but that's a separate issue...
Anyway, bootstrapped/regtested on x86_64-linux and i686-linux successfully.
2024-09-28 Jakub Jelinek <ja...@redhat.com>
PR c++/116416
* expr.cc (categorize_ctor_elements_1): Fix up union handling of
*p_complete. Clear it only if num_fields is 0 and the union has
at least one FIELD_DECL, set to -1 if either union has no fields
and non-zero size, or num_fields is 1 and complete_ctor_at_level_p
returned false.
Hmm, complete_ctor_at_level_p also seems to need a change for this
understanding of union semantics: "every meaningful byte" depends on the
active member, so it seems like it should return true for a union iff
num_elts == 1.
Jason