[Bug target/71460] Copying structs can trap (on x86-32) due to SNaN to QNaN

ch3root at openwall dot com gcc-bugzilla@gcc.gnu.org
Sat Jun 11 21:25:00 GMT 2016


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71460

--- Comment #25 from Alexander Cherepanov <ch3root at openwall dot com> ---
On 06/10/2016 12:18 AM, joseph at codesourcery dot com wrote:
>>   > For *scalar* assignment that would be fine because of TS 18661-1 saying
>>   > "Whether C assignment (6.5.16) (and conversion as if by assignment)
>> to the
>>   > same format is an IEC 60559 convertFormat or copy operation is
>>   > implementation-defined, even if <fenv.h> defines the macro
>>   > FE_SNANS_ALWAYS_SIGNAL (F.2.1).".  It's rather less clear for struct
>>   > assignment.
>>
>> How is it compatible with C11, 6.3p2: "Conversion of an operand value to
>> a compatible type causes no change to the value or the representation."?
>> Ha, even changing representation is prohibited.
>
> That paragraph starts "Unless explicitly stated otherwise,".

Ugh, it's not in N1570.

> C11 does not
> consider sNaNs, and TS 18661 is explicitly stating otherwise for them.

You are talking about C11 + TS 18661 which is a different version of C. 
Even TS 18661-1 acknowledges that it's incompatible with C11, e.g. 
clause 12 reads: "[...] so that an implementation could not add 
signaling NaN support as an extension without contradicting C11." Will 
there be a new value for the -std option?

> "or the representation" is clearly nonsensical here.  When something is
> converted it's an rvalue, and rvalues aren't associated with
> representations unless and until stored in an object; they are just
> members of the set of values of a type (and on assignment, 6.2.6.1#8
> applies).

I'm not sure. It would be nice to have such a clear distinction between 
values and representations but C is tricky. What is the value of a union 
after memset? Suppose a value stored into an active member of a union 
admits several representations, is taking inactive member of this union 
(aka type-punning) is required to give the same result before and after 
applying lvalue-to-rvalue conversion to the union?

Heck, even the example that started this PR is not that easy. If a 
member of a structure has a trap representation what is the value of 
this structure? Is copying of this structure required to preserve the 
exact representation of this member? Can this trap representation be 
changed to a non-trap one?

And the whole DR 260 is written as if an indeterminate value is a value.

>>> Rather, it's OK for the loads
>>> to raise an exception because assignment / argument passing etc. can be
>>
>> I mean that "volatile double x; /* store sNaN to x */; x;" gives SIGFPE
>> currently. It doesn't look like (re)definitions of assignment etc. would
>> be applicable to this case.
>
> That seems rather like an omission in the specification relating to excess
> range and precision, which should be considered like a conversion
> (convertFormat) to the relevant wider format.

So the idea is that gcc on x86-32 with feenableexcept(FE_INVALID) could 
be made conforming with C11 + TS 18661? Is there anything there that 
allows to trap on a return from a function (when the result of the 
function is not used)? C11, 6.8.6.4p3, talks about a conversion "as if 
by assignment" only for a case of differing types and I don't see TS 
18661 patching this clause of C11.

I mean bug 57484 is more important case than lone loads from volatiles. 
But fixing the problem for lvalue-to-rvalue conversions in general 
should cover everything.


More information about the Gcc-bugs mailing list