https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71475

            Bug ID: 71475
           Summary: Optimization of copying into long double looses bytes
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ch3root at openwall dot com
  Target Milestone: ---

It seems that copying of bytes into a long double with memcpy or in some other
way is sometimes optimized by converting these bytes into long double at
compile-time and the process looses two higher bytes -- see the output "after
memcpy" with -O3 (bytes are printed starting from the big end).

Source code:

----------------------------------------------------------------------
#include <string.h>
#include <stdio.h>

int main()
{
  long double d0, d;

  memset(&d0, 'A', sizeof d0);
  d = d0;

  printf("after memset: %Lf\n", d);
  for (unsigned char *p = (unsigned char *)&d + sizeof d; p-- > (unsigned char
*)&d;)
    printf("%02x ", *p);
  printf("\n");
  printf("\n");

  memcpy(&d0, "AAAAAAAAAAAAAAAA", sizeof d0);
  d = d0;

  printf("after memcpy: %Lf\n", d);
  for (unsigned char *p = (unsigned char *)&d + sizeof d; p-- > (unsigned char
*)&d;)
    printf("%02x ", *p);
  printf("\n");
}
----------------------------------------------------------------------

Results:

----------------------------------------------------------------------
$ gcc -std=c11 -pedantic -Wall -Wextra test.c && ./a.out
after memset:
4355738269328914677589017258057892854796664468317418542308867623691847702374177028736570422722560.000000
00 00 00 00 00 00 41 41 41 41 41 41 41 41 41 41 

after memcpy:
4355738269328914677589017258057892854796664468317418542308867623691847702374177028736570422722560.000000
00 00 00 00 00 00 41 41 41 41 41 41 41 41 41 41 

$ gcc -std=c11 -pedantic -Wall -Wextra -O3 test.c && ./a.out
after memset:
4355738269328914677589017258057892854796664468317418542308867623691847702374177028736570422722560.000000
00 00 00 00 00 40 41 41 41 41 41 41 41 41 41 41 

after memcpy: 0.000000
00 00 00 00 00 40 00 00 41 41 41 41 41 41 41 41 
----------------------------------------------------------------------

gcc version: gcc (GCC) 7.0.0 20160608 (experimental)

Reply via email to