[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#325670: gcc-4.0: regression: generates wrong code for inlined memcpy



Package: gcc-4.0
Version: 4.0.1-2
Severity: important

When passing pointers to 4-byte types to memcpy(), gcc-4.0 generates
wrong code which assumes that these pointers are aligned at 4-byte
boundaries for purposes of optimization, ignoring the implicit cast to
(char *) in the prototype of memcpy().  I don't believe code should have
to explicitly cast to (char *) to guard against such optimizations, and
it seems that memcpy() is quite likely to be used for copying data from
unaligned locations to aligned buffers precisely because it's supposed
to be capable of unaligned access.  At least two packages, dhcp3 and
traceroute, have been reported as failing on sparc with bus errors when
built with gcc-4.0, because they use memcpy() to copy data from network
buffers where alignment is not guaranteed.

This bug has been reproduced with gcc-4.0 4.0.1-6 on vore using the
attached test case.  The test case is derived from the failing code in
dhcp3 (bug #321987, #325605).

vorlon@vore:~$ gcc-4.0 -g -o memcpytest ./memcpytest.c  && ./memcpytest
Bus error
vorlon@vore:~$ gcc-4.0 -DEXPLICIT_CAST -g -o memcpytest ./memcpytest.c && ./memcpytest
vorlon@vore:~$

Thanks,
-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
vorlon@debian.org                                   http://www.debian.org/
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>

int main() {
	unsigned char buf[512];
	unsigned bufix = 14;
	struct sockaddr_in from;
	struct sockaddr_in *src = (struct sockaddr_in *)(buf+bufix);

#ifdef EXPLICIT_CAST
	memcpy (&from.sin_addr, (char *)&src->sin_addr, 4);
#else
	memcpy (&from.sin_addr, &src->sin_addr, 4);
#endif

	exit(0);
}

Attachment: signature.asc
Description: Digital signature


Reply to: