[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