With -D_FORTIFY_SOURCE=2 memmove is folded to memcpy because of the restrict qualified arguments of the memmove wrapper. "Miscompiled" at -O1: typedef __SIZE_TYPE__ size_t; extern void *memmove (void *__dest, __const void *__src, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2))); extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__artificial__)) void * __attribute__ ((__nothrow__)) memmove (void *__restrict __dest, __const void *__restrict __src, size_t __len) { return __builtin___memmove_chk (__dest, __src, __len, __builtin_object_size (__dest, 0)); } extern void abort (void); void __attribute__((noinline,noclone)) foo(void *p, void *q) { memmove (p, q, 13); } int main() { char a[32] = "Hello World!"; foo (&a[1], a); if (strcmp (a, "HHello World!") != 0) abort (); foo (a, &a[1]); if (strcmp (a, "Hello World!") != 0) abort (); return 0; } But IMHO this is a serious glibc bug.
This really does look like a glibc bug rather than a GCC one. The Restrict usage there I really think is an invalid use of it.
Yep.