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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
let me explain a little bit more:

v w = {0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1};
unsigned short *p = (unsigned short *)&w;
int main() {
  w.h = 1; // write to w via the struct

  return (short)(e(*p, 3) + *p - 4661) + *p == 4661 ? 0 : 1; // reads via
unsigned short

since bitfields and underlying types are not alias "compatible" the read of a
pointer and the write to w are infered not to the same variable so the read can
be moved before the write.
as seen by the assembly:
```
        mov     rax, QWORD PTR "p"[rip]
...
        movzx   ecx, WORD PTR [rax]
        or      BYTE PTR "w"[rip], 1
```
Either use an union for the w to get the unsigned short value, memcpy or
-fno-strict-aliasing and you will get the correct result.

Reply via email to