History

default-initialization of bitfields

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

herman ten brugge committed 6 years ago

Commit 5c6356f1 parent 6d819d72 files · +56 −0Browse files

Unified · Split

2 files
  1. tccgen.c +25 −0
  2. tests/tcctest.c +31 −0
tccgen.c+25−0
@@ -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 */
7655static 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 the7671/* '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 based7672 object in section 'sec'. If 'sec' is NULL, it means stack based
7656 allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi7673 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)
tests/tcctest.c+31−0
@@ -1737,6 +1737,16 @@ int sinit23[2] = { "astring" ? sizeof("astring") : -1, · 1736 unmodified lines
1737 1737
1738int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */1738int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */
1739 1739
1740/* bitfield init */
1741struct bf_SS {unsigned int bit:1,bits31:31; };
1742struct bf_SS bf_init = { .bit = 1 };
1743struct bfn_SS {int a,b; struct bf_SS c; int d,e; };
1744struct bfn_SS bfn_init = { .c.bit = 1 };
1745struct bfa_SS {int a,b; struct bf_SS c[3]; int d,e; };
1746struct bfa_SS bfa_init = { .c[1].bit = 1 };
1747struct bf_SS bfaa_init[3] = { [1].bit = 1 };
1748struct bf_SS bfaa_vinit[] = { [2].bit = 1 };
1749
1740extern int external_inited = 42;1750extern int external_inited = 42;
1741 1751
1742void init_test(void)1752void 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
1856void switch_uc(unsigned char uc)1887void switch_uc(unsigned char uc)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t