https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81977
Bug ID: 81977
Summary: Possible issue with inline memcpy with packed
structures
Product: gcc
Version: 6.3.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: vvarada at codeaurora dot org
Target Milestone: ---
g++ -DOUTER bug.cc -Wall -Wextra -fno-strict-aliasing -fwrapv
The following source yields different results when building with and without
optimizations (-O2). Compiling source did not result in any warnings.
Without: optimizations it prints 0xabcd which is expected
With -O2 optimization it prints 0x1617
The issue appears to be due to incorrect offsets being computed for the
relevant fields resulting from the inlining of memcpy.
If you look at the disassembly with -O2 the %edi argument on X64 is set to a
constant 0x1617 (5655 decimal) indicating the bug is at the compiler optimizer
itself.
By changing the size of *uint16_t header_info[2];* one gets different results
with -O2 as it picks different portions of _prefz.z for _pref.x.
Thanks,
-Vijay
---
#include
#include
#include
using namespace std;
void printval(int x) __attribute__((noinline));
void printval(int x)
{
cout << hex << x << endl;
}
#define PACKED __attribute__((packed, aligned(1)))
typedef struct
{
uint16_t x ;
uint16_t y ;
uint64_t z ;
} PACKED TestMsgType;
struct Payload
{
uint16_t header_info[2];
TestMsgType _pref;
void Pack(uint8_t *buffer)
{
memcpy(buffer, &_pref, sizeof(_pref));
}
void UnPack(uint8_t *buffer)
{
memcpy(&_pref, buffer, sizeof(_pref));
}
};
struct Msg
{
Payload _payload;
void Pack(uint8_t *buffer)
{
_payload.Pack(buffer);
}
void UnPack(uint8_t *buffer)
{
_payload.UnPack(buffer);
}
};
int main()
{
uint8_t * buffer = new uint8_t [30];
Msg msg;
Msg msg1;
msg._payload._pref.x = 0xabcd;
msg._payload._pref.y = 0xa;
msg._payload._pref.z = 0x0001020304051617;
msg.Pack(&buffer[0]);
msg1.UnPack(&buffer[0]);
printval(msg1._payload._pref.x);
delete [] buffer;
}