tccgen.c: Check struct/union size for bitfield. tests/tcctest.c: Add test code.
Unified · Split
| @@ -7339,7 +7339,7 @@ static void init_putz(Section *sec, unsigned long c, int size) · 7338 unmodified lines | |||
| 7339 | 'al' contains the already initialized length of the | 7339 | 'al' contains the already initialized length of the |
| 7340 | current container (starting at c). This returns the new length of that. */ | 7340 | current container (starting at c). This returns the new length of that. */ |
| 7341 | static int decl_designator(CType *type, Section *sec, unsigned long c, | 7341 | static int decl_designator(CType *type, Section *sec, unsigned long c, |
| 7342 | Sym **cur_field, int flags, int al) | 7342 | Sym **cur_field, int flags, int al, int size) |
| 7343 | { | 7343 | { |
| 7344 | Sym *s, *f; | 7344 | Sym *s, *f; |
| 7345 | int index, index_last, align, l, nb_elems, elem_size; | 7345 | 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, · 82 unmodified lines | |||
| 7428 | ensures that it even works with designators) */ | 7428 | ensures that it even works with designators) */ |
| 7429 | if (!(flags & DIF_SIZE_ONLY)) { | 7429 | if (!(flags & DIF_SIZE_ONLY)) { |
| 7430 | int zlen = c - (corig + al); | 7430 | int zlen = c - (corig + al); |
| 7431 | if (type->t & VT_BITFIELD) /* must include current field too */ | 7431 | if (type->t & VT_BITFIELD) { /* must include current field too */ |
| 7432 | zlen += type_size(type, &align); | 7432 | zlen += type_size(type, &align); |
| 7433 | if (al + zlen > size) | ||
| 7434 | zlen = size - al; | ||
| 7435 | } | ||
| 7433 | if (zlen > 0) | 7436 | if (zlen > 0) |
| 7434 | init_putz(sec, corig + al, zlen); | 7437 | init_putz(sec, corig + al, zlen); |
| 7435 | } | 7438 | } |
| @@ -7783,7 +7786,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 347 unmodified lines | |||
| 7783 | do_init_list: | 7786 | do_init_list: |
| 7784 | len = 0; | 7787 | len = 0; |
| 7785 | while (tok != '}' || (flags & DIF_HAVE_ELEM)) { | 7788 | while (tok != '}' || (flags & DIF_HAVE_ELEM)) { |
| 7786 | len = decl_designator(type, sec, c, &f, flags, len); | 7789 | len = decl_designator(type, sec, c, &f, flags, len, n*size1); |
| 7787 | flags &= ~DIF_HAVE_ELEM; | 7790 | flags &= ~DIF_HAVE_ELEM; |
| 7788 | if (type->t & VT_ARRAY) { | 7791 | if (type->t & VT_ARRAY) { |
| 7789 | ++indexsym.c; | 7792 | ++indexsym.c; |
| @@ -1746,6 +1746,8 @@ struct bfa_SS {int a,b; struct bf_SS c[3]; int d,e; }; · 1745 unmodified lines | |||
| 1746 | struct bfa_SS bfa_init = { .c[1].bit = 1 }; | 1746 | struct bfa_SS bfa_init = { .c[1].bit = 1 }; |
| 1747 | struct bf_SS bfaa_init[3] = { [1].bit = 1 }; | 1747 | struct bf_SS bfaa_init[3] = { [1].bit = 1 }; |
| 1748 | struct bf_SS bfaa_vinit[] = { [2].bit = 1 }; | 1748 | struct bf_SS bfaa_vinit[] = { [2].bit = 1 }; |
| 1749 | struct b2_SS {long long int field : 52; long long int pad : 12; }; | ||
| 1750 | struct b2_SS bf_init2 = {0xFFF000FFF000FLL, 0x123}; | ||
| 1749 | 1751 | ||
| 1750 | extern int external_inited = 42; | 1752 | extern int external_inited = 42; |
| 1751 | 1753 | ||
| @@ -1771,6 +1773,7 @@ void init_test(void) · 19 unmodified lines | |||
| 1771 | struct bfa_SS bfa_finit = { .c[1].bit = 1 }; | 1773 | struct bfa_SS bfa_finit = { .c[1].bit = 1 }; |
| 1772 | struct bf_SS bfaa_finit[3] = { [1].bit = 1 }; | 1774 | struct bf_SS bfaa_finit[3] = { [1].bit = 1 }; |
| 1773 | struct bf_SS bfaa_fvinit[] = { [2].bit = 1 }; | 1775 | struct bf_SS bfaa_fvinit[] = { [2].bit = 1 }; |
| 1776 | struct b2_SS bf_finit2 = {0xFFF000FFF000FLL, 0x123}; | ||
| 1774 | 1777 | ||
| 1775 | printf("sinit1=%d\n", sinit1); | 1778 | printf("sinit1=%d\n", sinit1); |
| 1776 | printf("sinit2=%d\n", sinit2); | 1779 | printf("sinit2=%d\n", sinit2); |