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.

Reply via email to