https://gcc.gnu.org/bugzilla/show_bug.cgi?id=32667

--- Comment #21 from Nadav Har'El <nyh at math dot technion.ac.il> ---
This old problem has become a real problem in gcc 12 with a real effect on
incorrect code generation, where code that copies an object was incorrectly
"optimized" to use __builtin_memcpy() instead of __builtin_memmove() even
though the source and destination objects may overlap - and it turns out that
__builtin_memcpy() may produce incorrect results for overlapping addresses.

This bug was discovered in the OSv project
https://github.com/cloudius-systems/osv/issues/1212 with code that doesn't
(obviously) call __builtin_memcpy() directly, but rather had a 27-character
type being copied and the compiler implemented this copy with a call to
__builtin_memcpy(). Here is an example of code which generates the wrong
results (note the missing "c" in the result and unexpectedly doubled "g"):

#include <cstdio>
int main(){
    char buf[128] = "0123456789abcdefghijklmnopqrstuvwxyz";
    struct [[gnu::packed]] data {
        char x[27];
    };
    void *p0 = buf;
    void *p1 = &buf[1];
    *static_cast<data*>(p0) = *static_cast<const data*>(p1);
    printf("%s", buf);
}

Reply via email to