This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/81977] New: Possible issue with inline memcpy with packed structures


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 <iostream>
#include <cstdint>
#include <cstring>

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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]