Fix bitfields init : tiny solution
tccgen.c: Check struct/union size for bitfield. tests/tcctest.c: Add test code.
This commit is contained in:
parent
89ea62481d
commit
8fd7a384e2
2 changed files with 9 additions and 3 deletions
9
tccgen.c
9
tccgen.c
|
|
@ -7339,7 +7339,7 @@ static void init_putz(Section *sec, unsigned long c, int size)
|
||||||
'al' contains the already initialized length of the
|
'al' contains the already initialized length of the
|
||||||
current container (starting at c). This returns the new length of that. */
|
current container (starting at c). This returns the new length of that. */
|
||||||
static int decl_designator(CType *type, Section *sec, unsigned long c,
|
static int decl_designator(CType *type, Section *sec, unsigned long c,
|
||||||
Sym **cur_field, int flags, int al)
|
Sym **cur_field, int flags, int al, int size)
|
||||||
{
|
{
|
||||||
Sym *s, *f;
|
Sym *s, *f;
|
||||||
int index, index_last, align, l, nb_elems, elem_size;
|
int index, index_last, align, l, nb_elems, elem_size;
|
||||||
|
|
@ -7428,8 +7428,11 @@ static int decl_designator(CType *type, Section *sec, unsigned long c,
|
||||||
ensures that it even works with designators) */
|
ensures that it even works with designators) */
|
||||||
if (!(flags & DIF_SIZE_ONLY)) {
|
if (!(flags & DIF_SIZE_ONLY)) {
|
||||||
int zlen = c - (corig + al);
|
int zlen = c - (corig + al);
|
||||||
if (type->t & VT_BITFIELD) /* must include current field too */
|
if (type->t & VT_BITFIELD) { /* must include current field too */
|
||||||
zlen += type_size(type, &align);
|
zlen += type_size(type, &align);
|
||||||
|
if (al + zlen > size)
|
||||||
|
zlen = size - al;
|
||||||
|
}
|
||||||
if (zlen > 0)
|
if (zlen > 0)
|
||||||
init_putz(sec, corig + al, zlen);
|
init_putz(sec, corig + al, zlen);
|
||||||
}
|
}
|
||||||
|
|
@ -7783,7 +7786,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
do_init_list:
|
do_init_list:
|
||||||
len = 0;
|
len = 0;
|
||||||
while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
|
while (tok != '}' || (flags & DIF_HAVE_ELEM)) {
|
||||||
len = decl_designator(type, sec, c, &f, flags, len);
|
len = decl_designator(type, sec, c, &f, flags, len, n*size1);
|
||||||
flags &= ~DIF_HAVE_ELEM;
|
flags &= ~DIF_HAVE_ELEM;
|
||||||
if (type->t & VT_ARRAY) {
|
if (type->t & VT_ARRAY) {
|
||||||
++indexsym.c;
|
++indexsym.c;
|
||||||
|
|
|
||||||
|
|
@ -1746,6 +1746,8 @@ struct bfa_SS {int a,b; struct bf_SS c[3]; int d,e; };
|
||||||
struct bfa_SS bfa_init = { .c[1].bit = 1 };
|
struct bfa_SS bfa_init = { .c[1].bit = 1 };
|
||||||
struct bf_SS bfaa_init[3] = { [1].bit = 1 };
|
struct bf_SS bfaa_init[3] = { [1].bit = 1 };
|
||||||
struct bf_SS bfaa_vinit[] = { [2].bit = 1 };
|
struct bf_SS bfaa_vinit[] = { [2].bit = 1 };
|
||||||
|
struct b2_SS {long long int field : 52; long long int pad : 12; };
|
||||||
|
struct b2_SS bf_init2 = {0xFFF000FFF000FLL, 0x123};
|
||||||
|
|
||||||
extern int external_inited = 42;
|
extern int external_inited = 42;
|
||||||
|
|
||||||
|
|
@ -1771,6 +1773,7 @@ void init_test(void)
|
||||||
struct bfa_SS bfa_finit = { .c[1].bit = 1 };
|
struct bfa_SS bfa_finit = { .c[1].bit = 1 };
|
||||||
struct bf_SS bfaa_finit[3] = { [1].bit = 1 };
|
struct bf_SS bfaa_finit[3] = { [1].bit = 1 };
|
||||||
struct bf_SS bfaa_fvinit[] = { [2].bit = 1 };
|
struct bf_SS bfaa_fvinit[] = { [2].bit = 1 };
|
||||||
|
struct b2_SS bf_finit2 = {0xFFF000FFF000FLL, 0x123};
|
||||||
|
|
||||||
printf("sinit1=%d\n", sinit1);
|
printf("sinit1=%d\n", sinit1);
|
||||||
printf("sinit2=%d\n", sinit2);
|
printf("sinit2=%d\n", sinit2);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue