On Sat, Jan 5, 2013 at 5:35 PM, Richard Biener
<richard.guent...@gmail.com> wrote:
> On Fri, Jan 4, 2013 at 11:35 PM, Andreas Schwab <sch...@linux-m68k.org> wrote:
>> Janne Blomqvist <blomqvist.ja...@gmail.com> writes:
>>
>>> diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c
>>> index c8ecc3a..bf2250a 100644
>>> --- a/libgfortran/io/file_pos.c
>>> +++ b/libgfortran/io/file_pos.c
>>> @@ -140,15 +140,21 @@ unformatted_backspace (st_parameter_filepos *fpp, 
>>> gfc_unit *u)
>>>       }
>>>        else
>>>       {
>>> +       uint32_t u32;
>>> +       uint64_t u64;
>>>         switch (length)
>>>           {
>>>           case sizeof(GFC_INTEGER_4):
>>> -           reverse_memcpy (&m4, p, sizeof (m4));
>>> +           memcpy (&u32, p, sizeof (u32));
>>> +           u32 = __builtin_bswap32 (u32);
>>> +           m4 = *(GFC_INTEGER_4*)&u32;
>>
>> Isn't that an aliasing violation?
>
> It looks like one.  Why not simply do
>
>    m4 = (GFC_INTEGER_4) u32;
>
> ?  I suppose GFC_INTEGER_4 is always the same size as uint32_t but signed?

Yes, GFC_INTEGER_4 is a typedef for int32_t. As for why I didn't do
the above, C99 6.3.1.3(3) says that if the unsigned value is outside
the range of the signed variable, the result is
implementation-defined. Though I suppose the sensible
"implementation-defined behavior" in this case on a two's complement
target is to just do a bitwise copy.

Anyway, to be really safe one could use memcpy instead; the compiler
optimizes small fixed size memcpy's just fine. Updated patch attached.


-- 
Janne Blomqvist

Attachment: bswap2.diff
Description: Binary data

Reply via email to