bitfields init : tiny solution

This replaces commit 5c6356ff8e,
except the tests.
This commit is contained in:
grischka 2020-09-18 22:53:41 +02:00
parent 5c6356ff8e
commit 8cb3e5368f
1 changed files with 9 additions and 27 deletions

View File

@ -7423,10 +7423,17 @@ static int decl_designator(CType *type, Section *sec, unsigned long c,
c += f->c;
}
}
/* must put zero in holes (note that doing it that way
ensures that it even works with designators) */
if (!(flags & DIF_SIZE_ONLY) && c - corig > al)
init_putz(sec, corig + al, c - corig - al);
if (!(flags & DIF_SIZE_ONLY)) {
int zlen = c - (corig + al);
if (type->t & VT_BITFIELD) /* must include current field too */
zlen += type_size(type, &align);
if (zlen > 0)
init_putz(sec, corig + al, zlen);
}
decl_initializer(type, sec, c, flags & ~DIF_FIRST);
/* XXX: make it more general */
@ -7651,23 +7658,6 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
}
}
/* Check for bitfield in struct/union recursive */
static int check_bf(Sym *f)
{
while (f->next) {
f = f->next;
if ((f->type.t & VT_BITFIELD) ||
((f->type.t & VT_BTYPE) == VT_STRUCT && check_bf(f->type.ref)))
return 1;
if (f->type.t & VT_ARRAY) {
Sym *r = f->type.ref;
if (((r->type.t & VT_BTYPE) == VT_STRUCT && check_bf(r->type.ref)))
return 1;
}
}
return 0;
}
/* 't' contains the type and storage info. 'c' is the offset of the
object in section 'sec'. If 'sec' is NULL, it means stack based
allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
@ -7705,11 +7695,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
t1 = pointed_type(type);
size1 = type_size(t1, &align1);
if (!(flags & DIF_SIZE_ONLY) &&
(s->type.t & VT_BTYPE) == VT_STRUCT && check_bf (s->type.ref))
/* If there is a bitfield in array clear it */
init_putz(sec, c, size1 * n);
no_oblock = 1;
if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
tok == '{') {
@ -7839,9 +7824,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
s = type->ref;
f = s->next;
n = s->c;
if (!(flags & DIF_SIZE_ONLY) && check_bf (s))
/* If there is a bitfield in struct/union clear it */
init_putz(sec, c, n);
goto do_init_list;
} else if (tok == '{') {
if (flags & DIF_HAVE_ELEM)