[PATCH] c++: Add __builtin_bit_cast to implement std::bit_cast [PR93121]
Jason Merrill
jason@redhat.com
Wed Sep 2 21:52:04 GMT 2020
On 8/27/20 6:19 AM, Richard Biener wrote:
> On Thu, 27 Aug 2020, Jakub Jelinek wrote:
>
>> On Fri, Jul 31, 2020 at 04:28:05PM -0400, Jason Merrill via Gcc-patches wrote:
>>> On 7/31/20 6:06 AM, Jakub Jelinek wrote:
>>>> On Fri, Jul 31, 2020 at 10:54:46AM +0100, Jonathan Wakely wrote:
>>>>>> Does the standard require that somewhere? Because that is not what the
>>>>>> compiler implements right now.
>>>>>
>>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78620
>>>>
>>>> But does that imply that all CONSTRUCTORs without CONSTRUCTOR_NO_CLEARING
>>>> need to be treated that way? I mean, aren't such CONSTRUCTORs used also for
>>>> other initializations?
>>>
>>> Yes, they are also used to represent constant values of classes that are
>>> initialized by constexpr constructor.
>>>
>>>> And, are the default copy constructors or assignment operators supposed to
>>>> also copy the padding bits, or do they become unspecified again through
>>>> that?
>>>
>>> For a non-union class, a defaulted copy is defined as memberwise copy, not a
>>> copy of the entire object representation. So I guess strictly speaking the
>>> padding bits do become unspecified. But I think if the copy is trivial, in
>>> practice all implementations do copy the object representation; perhaps the
>>> specification should adjust accordingly.
>>
>> Sorry for not responding earlier. I think at least in GCC there is no
>> guarantee the copying is copying the object representation rather than
>> memberwise copy, both are possible, depending e.g. whether SRA happens or
>> not.
>
> Note we've basically settled on that SRA needs to copy padding and that
> GIMPLE copies all bytes for aggregate copies and thus
>
> x = {}
>
> is equivalent to a memset.
>
>> So, shouldn't we have a new CONSTRUCTOR flag that will represent whether
>> padding bits are cleared or not and then use it e.g. in the gimplifier?
>> Right now the gimplifier only adds first zero initialization if
>> CONSTRUCTOR_NO_CLEARING is not set and some initializers are not present,
>> so if there is a new flag, we'd need to in that case find out if there are
>> any padding bits and do the zero initialization in that case.
>> A question is if GIMPLE var = {}; statement (empty CONSTRUCTOR) is handled
>> as zero initialization of also the padding bits, or if we should treat it
>> that way only if the CONSTRUCTOR on the rhs has the new bit set and e.g.
>> when lowering memset 0 into var = {}; set the bit too.
>> From what I understood on IRC, D has similar need for zero initialization of
>> padding.
>
> Now indeed the gimplifier will turn a aggregate CTOR initialization
> to memberwise init without caring for padding. Which means GENERIC
> has the less strict semantics and we indeed would need some CTOR flag
> to tell whether padding is implicitely zero or undefined?
CONSTRUCTOR_NO_CLEARING would seem to already mean that, but the C++
front end uses it just to indicate whether some fields are
uninitialized. I suppose C++ could use a LANG_FLAG for that instead of
the generic flag.
>> In the testcase below, what is and what is not UB?
>>
>> #include <bit>
>>
>> struct S { int a : 31; int b; };
>> struct T { int a, b; };
>>
>> constexpr int
>> foo ()
>> {
>> S a = S ();
>> S b = { 0, 0 };
>> S c = a;
>> S d;
>> S e;
>> d = a;
>> e = S ();
>> int u = std::bit_cast (T, a).a; // Is this well defined due to value initialization of a?
>> int v = std::bit_cast (T, b).a; // But this is invalid, right? There is no difference in the IL though.
>> int w = std::bit_cast (T, c).a; // And this is also invalid, or are default copy ctors required to copy padding bits?
>> int x = std::bit_cast (T, d).a; // Similarly for default copy assignment operators...
>> int y = std::bit_cast (T, e).a; // And this too?
>> int z = std::bit_cast (T, S ()).a; // This one is well defined?
>> return u + v + w + x + y + z;
>> }
>>
>> constexpr int x = foo ();
>>
>> Jakub
>>
>>
>
More information about the Gcc-patches
mailing list