https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69482
Bug ID: 69482 Summary: Writing through pointers to volatile not always preserved Product: gcc Version: unknown Status: UNCONFIRMED Severity: major Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: wipedout at yandex dot ru Target Milestone: --- I'm trying this on http://gcc.godbolt.org/ The compiler selected is "x86 gcc 5.3.0", the command line option string is "-x c -std=c99 -O3" This is the code (note pointer to volatile): #include <stddef.h> static void memset_s(void* s, size_t n) { volatile unsigned char * p = s; for(size_t i = 0; i < n; ++i) { p[i] = 0; } } void test() { unsigned char x[4]; memset_s(x, sizeof x); } This is the emitted assembly: test: rep ret Same happens when size of array is 1 and 2. With all other array sizes writes are preserved. For example, this is emitted for array of size 3: test: movb $0, -24(%rsp) movb $0, -23(%rsp) movb $0, -22(%rsp) ret and this is emitted for array of size 5: test: movb $0, -24(%rsp) movb $0, -23(%rsp) movb $0, -22(%rsp) movb $0, -21(%rsp) movb $0, -20(%rsp) ret This is not reproduced in "x86 gcc 4.5.3" but is reproduced in "x86 gcc 4.6.4" and later. This isn't reproduced in clang. "secure memset" implementation as above is widely used to overwrite memory previously used to store encryption keys, passwords and the like. Cases with size hardcoded and being 1, 2 or 4 look dumb but I have no idea what exactly causes this unexpected code emission and how serious the real impact is.