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
76517651 }
76527652 }
76537653
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+
76547671 /* 't' contains the type and storage info. 'c' is the offset of the
76557672 object in section 'sec'. If 'sec' is NULL, it means stack based
76567673 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
76887705 t1 = pointed_type(type);
76897706 size1 = type_size(t1, &align1);
76907707
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+
76917713 no_oblock = 1;
76927714 if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
76937715 tok == '{') {
@@ -7817,6 +7839,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 123 unmodified lines
78177839 s = type->ref;
78187840 f = s->next;
78197841 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);
78207845 goto do_init_list;
78217846 } else if (tok == '{') {
78227847 if (flags & DIF_HAVE_ELEM)
tests/tcctest.c+31−0
@@ -1737,6 +1737,16 @@ int sinit23[2] = { "astring" ? sizeof("astring") : -1, · 1736 unmodified lines
17371737
17381738 int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */
17391739
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+
17401750 extern int external_inited = 42;
17411751
17421752 void init_test(void)
@@ -1756,6 +1766,11 @@ void init_test(void) · 13 unmodified lines
17561766 int zero = 0;
17571767 /* Addresses on non-weak symbols are non-zero, but not the access itself */
17581768 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 };
17591774
17601775 printf("sinit1=%d\n", sinit1);
17611776 printf("sinit2=%d\n", sinit2);
@@ -1851,6 +1866,22 @@ void init_test(void) · 89 unmodified lines
18511866 printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
18521867 printf("sinit24=%d\n", sinit24);
18531868 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);
18541885 }
18551886
18561887 void 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