[Bug middle-end/105805] New: -fstrict-volatile-bitfields can read beyond the end of the bitfield
rsandifo at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Jun 1 16:28:42 GMT 2022
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105805
Bug ID: 105805
Summary: -fstrict-volatile-bitfields can read beyond the end of
the bitfield
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: rsandifo at gcc dot gnu.org
Target Milestone: ---
There are a few PRs related to -fstrict-volatile-bitfields, but this
one didn't seem to be a dup.
For:
-----------------------------------------------------------
struct S1 { volatile int a : 16; } __attribute__((packed));
struct S2 { _Alignas(4) struct S1 b; volatile short c; };
_Static_assert (sizeof (struct S2) == 4);
int foo (struct S2 *ptr) { return ptr->b.a; }
-----------------------------------------------------------
b and c are both 16-bit fields, but ptr->b.a uses a 32-bit access.
It therefore loads volatile field c despite c not being in the
same bitfield group as b.a:
foo:
ldr w0, [x0]
sxth w0, w0
ret
The problem seems to be that get_inner_reference commits too
early to using the mode of the bitfield's underlying type,
and we rely on:
/* The memory must be sufficiently aligned for a MODESIZE access.
This condition guarantees, that the memory access will not
touch anything after the end of the structure. */
if (MEM_ALIGN (op0) < modesize)
return false;
from strict_volatile_bitfield_p to roll back incorrect decisions.
But in this case, the layout of S2 guarantees 4-byte alignment,
so the opt-out doesn't work.
I was originally looking at the simpler:
-----------------------------------------------------------
struct S1 { volatile int a : 16; } __attribute__((packed));
struct S1 s;
int foo () { return s.a; }
-----------------------------------------------------------
which also exhibits the problem, but I guess it could be
argued in that case that the extra 2 bytes are guaranteed
to be dead space.
See also the testcase for PR69990.
More information about the Gcc-bugs
mailing list