Fixed initialization of union when it has an anonymous bit-field as the first member declaration.

This commit is contained in:
acqn 2023-11-15 21:32:24 +08:00
parent 5537b61e6a
commit 3b7af398a9
2 changed files with 27 additions and 20 deletions

View File

@ -511,18 +511,20 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers)
/* This may be an anonymous bit-field, in which case it doesn't
** have an initializer.
*/
if (SymIsBitField (TagSym) && (IsAnonName (TagSym->Name))) {
/* Account for the data and output it if we have at least a full
** byte. We may have more if there was storage unit overlap, for
** example two consecutive 7 bit fields. Those would be packed
** into 2 bytes.
*/
SI.ValBits += TagSym->Type->A.B.Width;
CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal));
/* TODO: Generalize this so any type can be used. */
CHECK (SI.ValBits <= LONG_BITS);
while (SI.ValBits >= CHAR_BITS) {
DefineBitFieldData (&SI);
if (SymIsBitField (TagSym) && IsAnonName (TagSym->Name)) {
if (!IsTypeUnion (T)) {
/* Account for the data and output it if we have at least a full
** byte. We may have more if there was storage unit overlap, for
** example two consecutive 7 bit fields. Those would be packed
** into 2 bytes.
*/
SI.ValBits += TagSym->Type->A.B.Width;
CHECK (SI.ValBits <= CHAR_BIT * sizeof(SI.BitVal));
/* TODO: Generalize this so any type can be used. */
CHECK (SI.ValBits <= LONG_BITS);
while (SI.ValBits >= CHAR_BITS) {
DefineBitFieldData (&SI);
}
}
/* Avoid consuming the comma if any */
goto NextMember;
@ -628,15 +630,15 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers)
/* Skip the comma next round */
SkipComma = 1;
NextMember:
/* Next member. For unions, only the first one can be initialized */
/* For unions, only the first named member can be initialized */
if (IsTypeUnion (T)) {
/* Union */
TagSym = 0;
} else {
/* Struct */
TagSym = TagSym->NextSym;
continue;
}
NextMember:
/* Next member */
TagSym = TagSym->NextSym;
}
if (HasCurly) {

View File

@ -1,5 +1,5 @@
/*
Copyright 2020 The cc65 Authors
Copyright 2020-2023 The cc65 Authors
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -25,6 +25,7 @@
#include <stdio.h>
typedef union {
const unsigned int : 1;
unsigned int bf;
struct {
@ -38,8 +39,12 @@ static unsigned char failures = 0;
int main (void)
{
bitfield_t bitfield = {0};
bitfield_t bitfield = { 42 };
printf ("Bitfield: %u\n", bitfield.bf);
if (bitfield.bf != 42) failures++;
bitfield.bf ^= 42;
printf ("Bitfield: %u\n", bitfield.bf);
if (bitfield.bf != 0) failures++;