We fold memcpy to direct assignments based on types of the pointed-to types of its arguments. This is completely wrong for C++ and wrong for C if neither source nor destination has a declared type. memcpy transfers the dynamic type of objects.
int main() { int i = 0; float f = 1.0; int *p = (int *)&f; __builtin_memcpy (&i, p, 4); if (*(float *)&i != 1.0) __builtin_abort (); return 0; } we already fold the memcpy to i = *(int * {ref-all})p; but that creates an access to i via an lvalue of type int. It needs to be all done via a ref-all access, thus *(<type-large-enough> * {ref-all})&i = *(<type-large-enough> * {ref-all})p; In C the testcase would invoke undefined behavior as i has a declared type but it is valid C++. The issue arises fixing std::tr1::functional::swap wrt its accesses to _Any_data. void swap(function& __x) { _Any_data __old_functor; __builtin_memcpy (&__old_functor, &_M_functor, sizeof (_Any_data)); __builtin_memcpy (&_M_functor, &__x._M_functor, sizeof (_Any_data)); __builtin_memcpy (&__x._M_functor, &__old_functor, sizeof (_Any_data)); _Manager_type __old_manager = _M_manager; is folded back to __old_functor = D.13016.D.8817._M_functor; D.13016.D.8817._M_functor = f.D.8817._M_functor; f.D.8817._M_functor = __old_functor; which wasn't the point of the whole excercise. -- Summary: memcpy folding overeager Product: gcc Version: 4.5.0 Status: UNCONFIRMED Keywords: wrong-code, alias Severity: normal Priority: P3 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: rguenth at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42834