[Bug c++/102401] std::bit_cast falls over, seemingly due to some invisible alignment requirements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102401 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #1 from Jakub Jelinek --- Why do you think GCC is not right? The Item class has 3 bytes of padding, and the Data class doesn't have any. So, when evaluated at runtime, it would be a UB, while during constant evaluation it has to be an error.
[Bug c++/102401] std::bit_cast falls over, seemingly due to some invisible alignment requirements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102401 Andrew Pinski changed: What|Removed |Added Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED --- Comment #2 from Andrew Pinski --- Yes this is the way the C++ standard is defined. Even clang rejects it. I would have thought __builtin_clear_padding could be used in constexpr but I was wrong.
[Bug c++/102401] std::bit_cast falls over, seemingly due to some invisible alignment requirements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102401 --- Comment #3 from Jakub Jelinek --- There are things that need to be clarified, in particular value initialization should clear even the padding bits, so supposedly std::bit_cast of Item() if the NSDMIs would be dropped might be well defined and ok in constexpr contexts (we don't implement that currently, and don't implement it even at runtime, we treat padding bits as always undefined), but the above testcase has a user defined constructor and therefore no zero initialization happens, and even if it wouldn't, any copying around (both copy construction and assignments) will make those bits undefined as well.
[Bug c++/102401] std::bit_cast falls over, seemingly due to some invisible alignment requirements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102401 --- Comment #4 from Jonathan Wakely --- (In reply to Jakub Jelinek from comment #3) > There are things that need to be clarified, in particular value > initialization should clear even the padding bits, so supposedly > std::bit_cast of Item() if the NSDMIs would be dropped might be well defined > and ok in constexpr contexts (we don't implement that currently, and don't > implement it even at runtime, we treat padding bits as always undefined), I think that's a bug. > but the above testcase has a user defined constructor and therefore no zero No it doesn't. It has no constructor that is user-declared, so a default constructor is implicitly defined as defaulted. That default constructor is non-trivial (because of the default member-initializers) but it's still implicitly defined. List-initialization with an empty init list means value-initialization. Since there is no user-provided default constructor, that means: "the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;" So it should be zero-initialized (which zeroes all padding) and then it should be default-initialized (which uses the implicitly-defined default constructor, which uses the NSDMIs). So the padding bits should be initialized, no?
[Bug c++/102401] std::bit_cast falls over, seemingly due to some invisible alignment requirements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102401 Jakub Jelinek changed: What|Removed |Added Resolution|INVALID |--- Last reconfirmed||2021-09-20 Ever confirmed|0 |1 Status|RESOLVED|REOPENED --- Comment #5 from Jakub Jelinek --- We need to fix PR78620 first. I think one thing is adding some CONSTRUCTOR_ZERO_PADDING flag on CONSTRUCTORs (meaning that padding is zero initialized), propagate it through the FE and handle in constexpr there and handle that during gimplification, either by __builtin_clear_padding or pre-zeroing the whole memory (TREE_STATIC vars don't need that of course). And then there is a question if we don't need further middle-end changes, because a mere struct assignment in the GIMPLE IL doesn't guarantee copying of the padding bits.
[Bug c++/102401] std::bit_cast falls over, seemingly due to some invisible alignment requirements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102401 Jonathan Wakely changed: What|Removed |Added Depends on||78620 --- Comment #6 from Jonathan Wakely --- std::bit_cast says the padding bits have unspecified values, so we don't necessarily need to copy them. We just can't reject them for being uninitialized. Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78620 [Bug 78620] C++11, Padding bytes not zero-intialized when POD is initialized with compiler generated default constructor
[Bug c++/102401] std::bit_cast falls over, seemingly due to some invisible alignment requirements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102401 --- Comment #7 from Jakub Jelinek --- Note, since r12-5789-gc57c910c945ac68ba9a7cda9b0f963173781d58c GCC implements https://wg21.link/P1272 which clarifies that the #c0 testcase is invalid. With unsigned char or std::byte instead of char in Data definition actually doing std::bit_cast(item) would be well defined, but not the copying of those bytes to d.