| Summary: | [4.6 Regression] Bogus memmove folding (?) | ||
|---|---|---|---|
| Product: | gcc | Reporter: | Richard Biener <rguenth> |
| Component: | tree-optimization | Assignee: | Not yet assigned to anyone <unassigned> |
| Status: | RESOLVED INVALID | ||
| Severity: | normal | CC: | zsojka |
| Priority: | P3 | Keywords: | alias, wrong-code |
| Version: | 4.6.0 | ||
| Target Milestone: | --- | ||
| Host: | Target: | ||
| Build: | Known to work: | ||
| Known to fail: | Last reconfirmed: | ||
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. |
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.