https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92486
Bug ID: 92486
Summary: Wrong optimization: padding in structs is not copied
even with memcpy
Product: gcc
Version: 9.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ch3root at openwall dot com
Target Milestone: ---
Sometimes padding in structs is not copied even with memcpy. AIUI this is
considered a bug in gcc (similar to pr71452 and pr71522). The code:
----------------------------------------------------------------------
#include <string.h>
#include <stdio.h>
struct s {
char c;
int i;
};
__attribute__((noinline,noclone))
void f(struct s *p, struct s *q)
{
struct s w = *q;
memcpy(&w, q, sizeof(struct s));
*p = w;
memcpy(p, &w, sizeof(struct s));
}
int main()
{
struct s x;
memset(&x, 1, sizeof(struct s));
struct s y;
memset(&y, 2, sizeof(struct s));
f(&y, &x);
for (unsigned char *p = (unsigned char *)&y; p < (unsigned char *)&y +
sizeof(struct s); p++)
printf("%d", *p);
printf("\n");
}
----------------------------------------------------------------------
According to https://godbolt.org/z/fSEGka, x86-64 gcc, versions from 6.3 to 9.2
(but not trunk), with options `-std=c11 -Wall -Wextra -pedantic -O3` miscompile
the function `f` and the program outputs `12221111` instead of `11111111`. I
guess that `memcpy`s are optimized away as they fully duplicate assignments,
then assignments are scalarized and the padding is lost.