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

            Bug ID: 65029
           Summary: aggregate copy invokes memcpy on overlapping regions
           Product: gcc
           Version: 4.9.2
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gmail dot com

According to 7.24.2.1 of C11, "If copying takes place between objects that
overlap, the behavior [of memcpy] is undefined."  The script below shows that
GCC generates code with undefined behavior for a strictly conforming C11
program (the code is the same with -fno-builtin-memcpy or -ffreestanding). 
This was brought to light by the valgrind error (also shown).

$ cat t.c && gcc -DMEMCPY -DN=65 -O2 -Wall -std=c11 t.c && ./a.out || gcc
-DN=65 -O2 -Wall -std=c11 t.c && valgrind ./a.out
#include <assert.h>
#include <stddef.h>

struct S {
    char c [N];
};

void __attribute__ ((weak))
foo (struct S *a, struct S *b)
{
    *a = *b;
}

#if MEMCPY

void* memcpy (void* restrict d, const void* restrict s, size_t n)
{
    typedef unsigned char UChar;
    UChar *pd;
    const UChar *ps;

    assert (d != s);

    for (pd = (UChar*)d, ps = (const UChar*)s; n--; ++pd, ++ps)
        *pd = *ps;
    return d;
}

#endif

int main (void) {
    struct S s = { { 0 } };
    foo (&s, &s);
    return 0;
}

a.out: t.c:22: memcpy: Assertion `d != s' failed.
Aborted
==62960== Memcheck, a memory error detector
==62960== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==62960== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==62960== Command: ./a.out
==62960== 
==62960== Source and destination overlap in memcpy(0xfff00eb30, 0xfff00eb30,
65)
==62960==    at 0x408C908: memcpy (in
/usr/lib64/valgrind/vgpreload_memcheck-ppc64be-linux.so)
==62960==    by 0x10000643: foo (in /home/remote/msebor/tmp/a.out)
==62960==    by 0x10000433: main (in /home/remote/msebor/tmp/a.out)
==62960== 
==62960== 
==62960== HEAP SUMMARY:
==62960==     in use at exit: 0 bytes in 0 blocks
==62960==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==62960== 
==62960== All heap blocks were freed -- no leaks are possible
==62960== 
==62960== For counts of detected and suppressed errors, rerun with: -v
==62960== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Reply via email to