From 8fd7a384e2facd4517b200ec8cc79966b3774684 Mon Sep 17 00:00:00 2001 From: herman ten brugge Date: Fri, 25 Sep 2020 12:23:48 +0200 Subject: [PATCH] Fix bitfields init : tiny solution tccgen.c: Check struct/union size for bitfield. tests/tcctest.c: Add test code. --- tccgen.c | 9 ++++++--- tests/tcctest.c | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tccgen.c b/tccgen.c index 52f2462..61ef787 100644 --- a/tccgen.c +++ b/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 current container (starting at c). This returns the new length of that. */ 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; 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) */ if (!(flags & DIF_SIZE_ONLY)) { 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); + if (al + zlen > size) + zlen = size - al; + } if (zlen > 0) init_putz(sec, corig + al, zlen); } @@ -7783,7 +7786,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, do_init_list: len = 0; 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; if (type->t & VT_ARRAY) { ++indexsym.c; diff --git a/tests/tcctest.c b/tests/tcctest.c index 48b20b9..71089b5 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.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 bf_SS bfaa_init[3] = { [1].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; @@ -1771,6 +1773,7 @@ void init_test(void) struct bfa_SS bfa_finit = { .c[1].bit = 1 }; struct bf_SS bfaa_finit[3] = { [1].bit = 1 }; struct bf_SS bfaa_fvinit[] = { [2].bit = 1 }; + struct b2_SS bf_finit2 = {0xFFF000FFF000FLL, 0x123}; printf("sinit1=%d\n", sinit1); printf("sinit2=%d\n", sinit2);