https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78995
Bug ID: 78995
Summary: A strange copy error caused by O3 optimization
Product: gcc
Version: 4.8.5
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: zhangfei1 at cffex dot com.cn
Target Milestone: ---
Created attachment 40464
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40464=edit
A demon to reproduce this bug
I come across a strange error while using the rte_memcpy function under gcc O3
optimization these days.
A demon codes are as attachment. The problems are detailed as following,
What I want to do is just to copy 4 Bytes from a buffer to another struct
variable, as the 'key codes' and 'copy function' shown in the tail.
But the source 4 Bytes is 0x11223344, while the copied 4 Bytes is 0x22110040.
What happens?
I have done more test, and the results are as following,
1) O0 optimization has no error, while O2 and O3 optimization has problem.
2) If I replace the copy function from rte_memcpy to memcpy, there will be no
error.
3) If I directly call the 'GetHeader function' in the constructor function,
there will be no error.
4) If I comment out the change endian codes, there will be no error.
5) If I replace the 'break' by 'return' in 'next function', there will be no
error.
I have done the test in gcc4.4.6 (Redhat6.3-x86_64), gcc 4.8.5
(Redhat7.2-x86_64), and gcc 5.2.1 (ubuntu15.10_x86_64). All of them have these
problems.
To run the demon:
1) just run the ./make.sh will be ok. This will compile the codes, and generate
the target file a.out.
Would anyone give some help to me?
Very thanks for your help.
/* *** key codes */
//memcpy(_fieldHeader, m_pCurr, 4);
rte_memcpy(_fieldHeader, m_pCurr, 4);
m_fieldHeader.FieldID = ((m_fieldHeader.FieldID&0x00ff)<<8)|
((m_fieldHeader.FieldID&0xff00)>>8);
m_fieldHeader.Size =((m_fieldHeader.Size&0x00ff)<<8)|
((m_fieldHeader.Size&0xff00)>>8);
char *p = m_pCurr;
fprintf(stdout, "src: 0x%02x%02x%02x%02x\n", *p,*(p+1),*(p+2),*(p+3));
p = (char*)(_fieldHeader);
fprintf(stdout, "dst: 0x%02x%02x%02x%02x\n", *p,*(p+1),*(p+2),*(p+3));
fflush(stdout);
/* copy function ***/
rte_memcpy(void *dst, const void *src, size_t n)
{
uintptr_t dstu = (uintptr_t)dst;
uintptr_t srcu = (uintptr_t)src;
*(uint32_t *)dstu = *(const uint32_t *)srcu;
}