[Bug c++/102401] std::bit_cast falls over, seemingly due to some invisible alignment requirements

2021-09-18 Thread jakub at gcc dot gnu.org via Gcc-bugs
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

2021-09-18 Thread pinskia at gcc dot gnu.org via Gcc-bugs
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

2021-09-18 Thread jakub at gcc dot gnu.org via Gcc-bugs
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

2021-09-18 Thread redi at gcc dot gnu.org via Gcc-bugs
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

2021-09-20 Thread jakub at gcc dot gnu.org via Gcc-bugs
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

2021-09-20 Thread redi at gcc dot gnu.org via Gcc-bugs
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

2022-01-12 Thread jakub at gcc dot gnu.org via Gcc-bugs
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.