mirror of
https://github.com/frida/tinycc
synced 2024-11-23 16:19:35 +03:00
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
This commit is contained in:
parent
6d819d7267
commit
5c6356ff8e
25
tccgen.c
25
tccgen.c
@ -7651,6 +7651,23 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for bitfield in struct/union recursive */
|
||||
static int check_bf(Sym *f)
|
||||
{
|
||||
while (f->next) {
|
||||
f = f->next;
|
||||
if ((f->type.t & VT_BITFIELD) ||
|
||||
((f->type.t & VT_BTYPE) == VT_STRUCT && check_bf(f->type.ref)))
|
||||
return 1;
|
||||
if (f->type.t & VT_ARRAY) {
|
||||
Sym *r = f->type.ref;
|
||||
if (((r->type.t & VT_BTYPE) == VT_STRUCT && check_bf(r->type.ref)))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 't' contains the type and storage info. 'c' is the offset of the
|
||||
object in section 'sec'. If 'sec' is NULL, it means stack based
|
||||
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,
|
||||
t1 = pointed_type(type);
|
||||
size1 = type_size(t1, &align1);
|
||||
|
||||
if (!(flags & DIF_SIZE_ONLY) &&
|
||||
(s->type.t & VT_BTYPE) == VT_STRUCT && check_bf (s->type.ref))
|
||||
/* If there is a bitfield in array clear it */
|
||||
init_putz(sec, c, size1 * n);
|
||||
|
||||
no_oblock = 1;
|
||||
if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
|
||||
tok == '{') {
|
||||
@ -7817,6 +7839,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||
s = type->ref;
|
||||
f = s->next;
|
||||
n = s->c;
|
||||
if (!(flags & DIF_SIZE_ONLY) && check_bf (s))
|
||||
/* If there is a bitfield in struct/union clear it */
|
||||
init_putz(sec, c, n);
|
||||
goto do_init_list;
|
||||
} else if (tok == '{') {
|
||||
if (flags & DIF_HAVE_ELEM)
|
||||
|
@ -1737,6 +1737,16 @@ int sinit23[2] = { "astring" ? sizeof("astring") : -1,
|
||||
|
||||
int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */
|
||||
|
||||
/* bitfield init */
|
||||
struct bf_SS {unsigned int bit:1,bits31:31; };
|
||||
struct bf_SS bf_init = { .bit = 1 };
|
||||
struct bfn_SS {int a,b; struct bf_SS c; int d,e; };
|
||||
struct bfn_SS bfn_init = { .c.bit = 1 };
|
||||
struct bfa_SS {int a,b; struct bf_SS c[3]; int d,e; };
|
||||
struct bfa_SS bfa_init = { .c[1].bit = 1 };
|
||||
struct bf_SS bfaa_init[3] = { [1].bit = 1 };
|
||||
struct bf_SS bfaa_vinit[] = { [2].bit = 1 };
|
||||
|
||||
extern int external_inited = 42;
|
||||
|
||||
void init_test(void)
|
||||
@ -1756,6 +1766,11 @@ void init_test(void)
|
||||
int zero = 0;
|
||||
/* Addresses on non-weak symbols are non-zero, but not the access itself */
|
||||
int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
|
||||
struct bf_SS bf_finit = { .bit = 1 };
|
||||
struct bfn_SS bfn_finit = { .c.bit = 1 };
|
||||
struct bfa_SS bfa_finit = { .c[1].bit = 1 };
|
||||
struct bf_SS bfaa_finit[3] = { [1].bit = 1 };
|
||||
struct bf_SS bfaa_fvinit[] = { [2].bit = 1 };
|
||||
|
||||
printf("sinit1=%d\n", sinit1);
|
||||
printf("sinit2=%d\n", sinit2);
|
||||
@ -1851,6 +1866,22 @@ void init_test(void)
|
||||
printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
|
||||
printf("sinit24=%d\n", sinit24);
|
||||
printf("linit18= %d %d\n", linit18[0], linit18[1]);
|
||||
printf ("bf1: %u %u\n", bf_init.bit, bf_init.bits31);
|
||||
printf ("bf2: %u %u\n", bf_finit.bit, bf_finit.bits31);
|
||||
printf ("bf3: %u %u\n", bfn_init.c.bit, bfn_init.c.bits31);
|
||||
printf ("bf4: %u %u\n", bfn_finit.c.bit, bfn_finit.c.bits31);
|
||||
for (i = 0; i < 3; i++)
|
||||
printf ("bf5[%d]: %u %u\n", i, bfa_init.c[i].bit, bfa_init.c[i].bits31);
|
||||
for (i = 0; i < 3; i++)
|
||||
printf ("bf6[%d]: %u %u\n", i, bfa_finit.c[i].bit, bfa_finit.c[i].bits31);
|
||||
for (i = 0; i < 3; i++)
|
||||
printf ("bf7[%d]: %u %u\n", i, bfaa_init[i].bit, bfaa_init[i].bits31);
|
||||
for (i = 0; i < 3; i++)
|
||||
printf ("bf8[%d]: %u %u\n", i, bfaa_finit[i].bit, bfaa_finit[i].bits31);
|
||||
for (i = 0; i < 3; i++)
|
||||
printf ("bf9[%d]: %u %u\n", i, bfaa_vinit[i].bit, bfaa_vinit[i].bits31);
|
||||
for (i = 0; i < 3; i++)
|
||||
printf ("bf10[%d]: %u %u\n", i, bfaa_fvinit[i].bit, bfaa_fvinit[i].bits31);
|
||||
}
|
||||
|
||||
void switch_uc(unsigned char uc)
|
||||
|
Loading…
Reference in New Issue
Block a user