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 | /* 't' contains the type and storage info. 'c' is the offset of the | 7671 | /* 't' contains the type and storage info. 'c' is the offset of the |
| 7655 | object in section 'sec'. If 'sec' is NULL, it means stack based | 7672 | object in section 'sec'. If 'sec' is NULL, it means stack based |
| 7656 | allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi | 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 | t1 = pointed_type(type); | 7705 | t1 = pointed_type(type); |
| 7689 | size1 = type_size(t1, &align1); | 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 | no_oblock = 1; | 7713 | no_oblock = 1; |
| 7692 | if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) || | 7714 | if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) || |
| 7693 | tok == '{') { | 7715 | tok == '{') { |
| @@ -7817,6 +7839,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 123 unmodified lines | |||
| 7817 | s = type->ref; | 7839 | s = type->ref; |
| 7818 | f = s->next; | 7840 | f = s->next; |
| 7819 | n = s->c; | 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 | goto do_init_list; | 7845 | goto do_init_list; |
| 7821 | } else if (tok == '{') { | 7846 | } else if (tok == '{') { |
| 7822 | if (flags & DIF_HAVE_ELEM) | 7847 | if (flags & DIF_HAVE_ELEM) |
| @@ -1737,6 +1737,16 @@ int sinit23[2] = { "astring" ? sizeof("astring") : -1, · 1736 unmodified lines | |||
| 1737 | 1737 | ||
| 1738 | int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */ | 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 | extern int external_inited = 42; | 1750 | extern int external_inited = 42; |
| 1741 | 1751 | ||
| 1742 | void init_test(void) | 1752 | void init_test(void) |
| @@ -1756,6 +1766,11 @@ void init_test(void) · 13 unmodified lines | |||
| 1756 | int zero = 0; | 1766 | int zero = 0; |
| 1757 | /* Addresses on non-weak symbols are non-zero, but not the access itself */ | 1767 | /* Addresses on non-weak symbols are non-zero, but not the access itself */ |
| 1758 | int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 }; | 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 | printf("sinit1=%d\n", sinit1); | 1775 | printf("sinit1=%d\n", sinit1); |
| 1761 | printf("sinit2=%d\n", sinit2); | 1776 | printf("sinit2=%d\n", sinit2); |
| @@ -1851,6 +1866,22 @@ void init_test(void) · 89 unmodified lines | |||
| 1851 | printf("sinit23= %d %d\n", sinit23[0], sinit23[1]); | 1866 | printf("sinit23= %d %d\n", sinit23[0], sinit23[1]); |
| 1852 | printf("sinit24=%d\n", sinit24); | 1867 | printf("sinit24=%d\n", sinit24); |
| 1853 | printf("linit18= %d %d\n", linit18[0], linit18[1]); | 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 | void switch_uc(unsigned char uc) | 1887 | void switch_uc(unsigned char uc) |