https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82224
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Alexander Cherepanov from comment #8) > On 2017-10-27 12:41, rguenth at gcc dot gnu.org wrote: > >> And with allocated memory (C; add placement new's for C++): > >> > >> ---------------------------------------------------------------------- > >> #include <stdlib.h> > >> #include <string.h> > >> #include <stdio.h> > >> > >> static long test(long *px, long long *py, void *pu) > >> { > >> *px = 0; > >> *py = 1; > >> > >> // change effective type from long long to long > >> long tmp; > >> memcpy(&tmp, pu, sizeof(tmp)); > >> memcpy(pu, &tmp, sizeof(tmp)); > > > > I believe this one is invalid - memcpy transfers the dynamic > > type and *pu is currently 'long long'. So it's either not > > changing the dynamic type because, well, the type transfers > > through 'tmp' or you are accessing 'tmp' with declared type > > long as 'long long'. > AIUI memcpy is always valid if there is enough space, no matter what > types its source and destination have. It accesses both of them as > arrays of chars -- C11, 7.24.1p1: "The header <string.h> declares one > type and several functions, and defines one macro useful for > manipulating arrays of character type and other objects treated as > arrays of character type." > > OTOH memcpy transfers effective type from the source to the destination > but only if the destination has no declared type -- C11, 6.5p6: "If a > value is copied into an object having no declared type using memcpy or > memmove, or is copied as an array of character type, then the effective > type of the modified object for that access and for subsequent accesses > that do not modify the value is the effective type of the object from > which the value is copied, if it has one." > Placement new in C++ can change dynamic types of objects with declared > type but I don't think there are such facilities in C. > > So in this example the first memcpy copies the value of *pu to tmp but > drops its effective type (long long) and the second memcpy copies the > value and passes the effective type of 'tmp' (long) along. Hmm, ok. For GCC internals the memcpy changes the dynamic type to "anything" (it uses alias-set zero reads/writes) so for GCC internals the testcase is valid in that the later read needs to consider the memcpy store as aliasing.