mirror of https://github.com/frida/tinycc
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
|
/* '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
|
object in section 'sec'. If 'sec' is NULL, it means stack based
|
||||||
allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi
|
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);
|
t1 = pointed_type(type);
|
||||||
size1 = type_size(t1, &align1);
|
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;
|
no_oblock = 1;
|
||||||
if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
|
if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) ||
|
||||||
tok == '{') {
|
tok == '{') {
|
||||||
|
@ -7817,6 +7839,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
s = type->ref;
|
s = type->ref;
|
||||||
f = s->next;
|
f = s->next;
|
||||||
n = s->c;
|
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;
|
goto do_init_list;
|
||||||
} else if (tok == '{') {
|
} else if (tok == '{') {
|
||||||
if (flags & DIF_HAVE_ELEM)
|
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 */
|
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;
|
extern int external_inited = 42;
|
||||||
|
|
||||||
void init_test(void)
|
void init_test(void)
|
||||||
|
@ -1756,6 +1766,11 @@ void init_test(void)
|
||||||
int zero = 0;
|
int zero = 0;
|
||||||
/* Addresses on non-weak symbols are non-zero, but not the access itself */
|
/* Addresses on non-weak symbols are non-zero, but not the access itself */
|
||||||
int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
|
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("sinit1=%d\n", sinit1);
|
||||||
printf("sinit2=%d\n", sinit2);
|
printf("sinit2=%d\n", sinit2);
|
||||||
|
@ -1851,6 +1866,22 @@ void init_test(void)
|
||||||
printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
|
printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
|
||||||
printf("sinit24=%d\n", sinit24);
|
printf("sinit24=%d\n", sinit24);
|
||||||
printf("linit18= %d %d\n", linit18[0], linit18[1]);
|
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)
|
void switch_uc(unsigned char uc)
|
||||||
|
|
Loading…
Reference in New Issue