The code: struct bf_SS {unsigned int bit:1,bits31:31; }; void func(void) { struct bf_SS bf_finit = { .bit = 1 }; } will not init bits31 to 0. tccgen.c: - check_bf: New function to check if bitfield is present in struct/union - decl_initializer: Call check_bf and set value to 0 is bitfield found tests/tcctest.c: - Add struct bitfield test code
Unified · Split
| @@ -7651,6 +7651,23 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 7650 unmodified lines | ||
| 7651 | 7651 | } |
| 7652 | 7652 | } |
| 7653 | 7653 | |
| 7654 | +/* Check for bitfield in struct/union recursive */ | |
| 7655 | +static int check_bf(Sym *f) | |
| 7656 | +{ | |
| 7657 | + while (f->next) { | |
| 7658 | + f = f->next; | |
| 7659 | + if ((f->type.t & VT_BITFIELD) || | |
| 7660 | + ((f->type.t & VT_BTYPE) == VT_STRUCT && check_bf(f->type.ref))) | |
| 7661 | + return 1; | |
| 7662 | + if (f->type.t & VT_ARRAY) { | |
| 7663 | + Sym *r = f->type.ref; | |
| 7664 | + if (((r->type.t & VT_BTYPE) == VT_STRUCT && check_bf(r->type.ref))) | |
| 7665 | + return 1; | |
| 7666 | + } | |
| 7667 | + } | |
| 7668 | + return 0; | |
| 7669 | +} | |
| 7670 | + | |
| 7654 | 7671 | /* 't' contains the type and storage info. 'c' is the offset of the |
| 7655 | 7672 | object in section 'sec'. If 'sec' is NULL, it means stack based |
| 7656 | 7673 | allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi |
| @@ -7688,6 +7705,11 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 31 unmodified lines | ||
| 7688 | 7705 | t1 = pointed_type(type); |
| 7689 | 7706 | size1 = type_size(t1, &align1); |
| 7690 | 7707 | |
| 7708 | + if (!(flags & DIF_SIZE_ONLY) && | |
| 7709 | + (s->type.t & VT_BTYPE) == VT_STRUCT && check_bf (s->type.ref)) | |
| 7710 | + /* If there is a bitfield in array clear it */ | |
| 7711 | + init_putz(sec, c, size1 * n); | |
| 7712 | + | |
| 7691 | 7713 | no_oblock = 1; |
| 7692 | 7714 | if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) || |
| 7693 | 7715 | tok == '{') { |
| @@ -7817,6 +7839,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 123 unmodified lines | ||
| 7817 | 7839 | s = type->ref; |
| 7818 | 7840 | f = s->next; |
| 7819 | 7841 | n = s->c; |
| 7842 | + if (!(flags & DIF_SIZE_ONLY) && check_bf (s)) | |
| 7843 | + /* If there is a bitfield in struct/union clear it */ | |
| 7844 | + init_putz(sec, c, n); | |
| 7820 | 7845 | goto do_init_list; |
| 7821 | 7846 | } else if (tok == '{') { |
| 7822 | 7847 | if (flags & DIF_HAVE_ELEM) |
| @@ -1737,6 +1737,16 @@ int sinit23[2] = { "astring" ? sizeof("astring") : -1, · 1736 unmodified lines | ||
| 1737 | 1737 | |
| 1738 | 1738 | int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */ |
| 1739 | 1739 | |
| 1740 | +/* bitfield init */ | |
| 1741 | +struct bf_SS {unsigned int bit:1,bits31:31; }; | |
| 1742 | +struct bf_SS bf_init = { .bit = 1 }; | |
| 1743 | +struct bfn_SS {int a,b; struct bf_SS c; int d,e; }; | |
| 1744 | +struct bfn_SS bfn_init = { .c.bit = 1 }; | |
| 1745 | +struct bfa_SS {int a,b; struct bf_SS c[3]; int d,e; }; | |
| 1746 | +struct bfa_SS bfa_init = { .c[1].bit = 1 }; | |
| 1747 | +struct bf_SS bfaa_init[3] = { [1].bit = 1 }; | |
| 1748 | +struct bf_SS bfaa_vinit[] = { [2].bit = 1 }; | |
| 1749 | + | |
| 1740 | 1750 | extern int external_inited = 42; |
| 1741 | 1751 | |
| 1742 | 1752 | void init_test(void) |
| @@ -1756,6 +1766,11 @@ void init_test(void) · 13 unmodified lines | ||
| 1756 | 1766 | int zero = 0; |
| 1757 | 1767 | /* Addresses on non-weak symbols are non-zero, but not the access itself */ |
| 1758 | 1768 | int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 }; |
| 1769 | + struct bf_SS bf_finit = { .bit = 1 }; | |
| 1770 | + struct bfn_SS bfn_finit = { .c.bit = 1 }; | |
| 1771 | + struct bfa_SS bfa_finit = { .c[1].bit = 1 }; | |
| 1772 | + struct bf_SS bfaa_finit[3] = { [1].bit = 1 }; | |
| 1773 | + struct bf_SS bfaa_fvinit[] = { [2].bit = 1 }; | |
| 1759 | 1774 | |
| 1760 | 1775 | printf("sinit1=%d\n", sinit1); |
| 1761 | 1776 | printf("sinit2=%d\n", sinit2); |
| @@ -1851,6 +1866,22 @@ void init_test(void) · 89 unmodified lines | ||
| 1851 | 1866 | printf("sinit23= %d %d\n", sinit23[0], sinit23[1]); |
| 1852 | 1867 | printf("sinit24=%d\n", sinit24); |
| 1853 | 1868 | printf("linit18= %d %d\n", linit18[0], linit18[1]); |
| 1869 | + printf ("bf1: %u %u\n", bf_init.bit, bf_init.bits31); | |
| 1870 | + printf ("bf2: %u %u\n", bf_finit.bit, bf_finit.bits31); | |
| 1871 | + printf ("bf3: %u %u\n", bfn_init.c.bit, bfn_init.c.bits31); | |
| 1872 | + printf ("bf4: %u %u\n", bfn_finit.c.bit, bfn_finit.c.bits31); | |
| 1873 | + for (i = 0; i < 3; i++) | |
| 1874 | + printf ("bf5[%d]: %u %u\n", i, bfa_init.c[i].bit, bfa_init.c[i].bits31); | |
| 1875 | + for (i = 0; i < 3; i++) | |
| 1876 | + printf ("bf6[%d]: %u %u\n", i, bfa_finit.c[i].bit, bfa_finit.c[i].bits31); | |
| 1877 | + for (i = 0; i < 3; i++) | |
| 1878 | + printf ("bf7[%d]: %u %u\n", i, bfaa_init[i].bit, bfaa_init[i].bits31); | |
| 1879 | + for (i = 0; i < 3; i++) | |
| 1880 | + printf ("bf8[%d]: %u %u\n", i, bfaa_finit[i].bit, bfaa_finit[i].bits31); | |
| 1881 | + for (i = 0; i < 3; i++) | |
| 1882 | + printf ("bf9[%d]: %u %u\n", i, bfaa_vinit[i].bit, bfaa_vinit[i].bits31); | |
| 1883 | + for (i = 0; i < 3; i++) | |
| 1884 | + printf ("bf10[%d]: %u %u\n", i, bfaa_fvinit[i].bit, bfaa_fvinit[i].bits31); | |
| 1854 | 1885 | } |
| 1855 | 1886 | |
| 1856 | 1887 | void switch_uc(unsigned char uc) |