GCC produced wrong code in gvfs-1.14.2-3.fc18.x86_64

Stephan Bergmann sbergman at redhat.com
Fri Mar 15 16:06:51 UTC 2013


On 03/15/2013 04:23 PM, Stephan Bergmann wrote:
> I happened to run across a problem with current gvfsd-sftp in x86_64
> Fedora 18 that is apparently due to bad code generated by GCC.
>
> The function
>
>> void
>> g_vfs_read_channel_send_seek_offset (GVfsReadChannel *read_channel,
>>                                      goffset offset)
>> {
>>   GVfsDaemonSocketProtocolReply reply;
>>   GVfsChannel *channel;
>>
>>   channel = G_VFS_CHANNEL (read_channel);
>>
>>   reply.type = g_htonl (G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SEEK_POS);
>>   reply.seq_nr = g_htonl (g_vfs_channel_get_current_seq_nr (channel));
>>   reply.arg1 = g_htonl (offset & 0xffffffff);
>>   reply.arg2 = g_htonl (offset >> 32);
>>
>>   g_vfs_channel_send_reply (channel, &reply, NULL, 0);
>> }
>
> in /usr/src/debug/gvfs-1.14.2/daemon/gvfsreadchannel.c shall split the
> signed 64 bit goffset offset into reply.arg1 and reply.arg2.  What
> happens though is that reply.arg2 erroneously contains the same
> (byte-swapped, due to g_htonl) low-order 32 bits as reply.arg1.  The
> generated code is
[...]
> Is this a known problem with (Fedora 18's) GCC?

Grr, sorry for the noise; appears to be rather a bug in 
glib2-devel-2.34.2-2.fc18.x86_64, where /usr/include/glib-2.0/glib/gtypes.h

> #    define GUINT32_SWAP_LE_BE(val) ((guint32) __builtin_bswap32 ((gint32) val))

misses parentheses around "val", so the above

> reply.arg2 = g_htonl (offset >> 32);

ultimately expands to

> reply.arg2 = ((((guint32) __builtin_bswap32 ((gint32) offset >> 32))));

(and building gvfs with -Werror would have nicely given it away, 
"warning: right shift count >= width of type [enabled by default]").

Stephan


More information about the devel mailing list