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&action=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(&m_fieldHeader, m_pCurr, 4);
    rte_memcpy(&m_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*)(&m_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;
}

Reply via email to