https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121693
Bug ID: 121693
Summary: forgets to clear the padding bits when converting a
_BitInt(1) on x86_64
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: vincent-gcc at vinc17 dot net
Target Milestone: ---
The x86_64 psABI https://gitlab.com/x86-psABIs/x86-64-ABI says about _BitInt:
"The value of the unused bits beyond the width of the _BitInt(N) value but
within the size of the _BitInt(N) are unspecified when stored in memory or
register."
So it is valid to read a _BitInt(N) with nonzero padding bits. However, GCC
does not clear them (contrary to Clang).
Testcase:
#include <stdio.h>
typedef union
{
_Bool b;
unsigned char c;
unsigned _BitInt(1) i;
} T;
int main (void)
{
T v;
volatile char c = 2;
v.c = c;
printf ("%d %d\n", (int) v.i, (int) (_Bool) (int) v.i);
return 0;
}
With the -O option, gcc (Debian 20250804-1) 16.0.0 20250804 (experimental)
[master r16-2729-g0d276cd378e] outputs "2 2" instead of "0 0" (ditto if
-fsanitize=undefined -fno-sanitize-recover are also used and with GCC 14.3.0).
The fact that the conversion to _Bool does not give 0 or 1 for the second value
shows that GCC is already confused by the v.i value.