mirror of
https://github.com/frida/tinycc
synced 2025-01-13 15:19:16 +03:00
Let init_putz one-time generation.
At the same time, increase the GCC style warning --------------------------------------------------------------------------- int main() { int a[10] = {[5]=5}; return 0; } Disassembly of section .text: 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 81 ec 30 00 00 00 sub $0x30,%rsp b: b8 05 00 00 00 mov $0x5,%eax 10: 89 45 ec mov %eax,-0x14(%rbp) 13: 48 b8 14 00 00 00 00 movabs $0x14,%rax 1a: 00 00 00 1d: 49 89 c2 mov %rax,%r10 20: b8 00 00 00 00 mov $0x0,%eax 25: 48 89 c6 mov %rax,%rsi 28: 48 8d 45 d8 lea -0x28(%rbp),%rax 2c: 48 89 c7 mov %rax,%rdi 2f: 4c 89 d2 mov %r10,%rdx 32: b8 00 00 00 00 mov $0x0,%eax 37: e8 fc ff ff ff callq 38 <main+0x38> 3c: 48 b8 10 00 00 00 00 movabs $0x10,%rax 43: 00 00 00 46: 49 89 c2 mov %rax,%r10 49: b8 00 00 00 00 mov $0x0,%eax 4e: 48 89 c6 mov %rax,%rsi 51: 48 8d 45 f0 lea -0x10(%rbp),%rax 55: 48 89 c7 mov %rax,%rdi 58: 4c 89 d2 mov %r10,%rdx 5b: b8 00 00 00 00 mov $0x0,%eax 60: e8 fc ff ff ff callq 61 <main+0x61> 65: b8 00 00 00 00 mov $0x0,%eax 6a: e9 00 00 00 00 jmpq 6f <main+0x6f> 6f: c9 leaveq 70: c3 retq After the patch 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 81 ec 30 00 00 00 sub $0x30,%rsp b: 48 b8 28 00 00 00 00 movabs $0x28,%rax 12: 00 00 00 15: 49 89 c2 mov %rax,%r10 18: b8 00 00 00 00 mov $0x0,%eax 1d: 48 89 c6 mov %rax,%rsi 20: 48 8d 45 d8 lea -0x28(%rbp),%rax 24: 48 89 c7 mov %rax,%rdi 27: 4c 89 d2 mov %r10,%rdx 2a: b8 00 00 00 00 mov $0x0,%eax 2f: e8 fc ff ff ff callq 30 <main+0x30> 34: b8 05 00 00 00 mov $0x5,%eax 39: 89 45 ec mov %eax,-0x14(%rbp) 3c: b8 00 00 00 00 mov $0x0,%eax 41: e9 00 00 00 00 jmpq 46 <main+0x46> 46: c9 leaveq 47: c3 retq ----------------------------------------------------------------------------------- "c5.c" int main() { // union st struct st { char c; short s; // char cc[]; }; // union st struct st ss = { 1, 2, 3}; // int a = ss; char cb[1] = {1,2,3}; return 0; } c5.c:12: warning: excess elements in struct initializer c5.c:14: warning: excess elements in array initializer c5.c:14: warning: excess elements in array initializer
This commit is contained in:
parent
89134dd7b0
commit
d316836008
116
tccgen.c
116
tccgen.c
@ -90,6 +90,7 @@ static void vla_runtime_type_size(CType *type, int *a);
|
||||
static void vla_sp_save(void);
|
||||
static int is_compatible_parameter_types(CType *type1, CType *type2);
|
||||
static void expr_type(CType *type);
|
||||
static int is_putz;
|
||||
static int is_force;
|
||||
|
||||
ST_FUNC void vpush64(int ty, unsigned long long v);
|
||||
@ -5039,11 +5040,11 @@ static void decl_designator(CType *type, Section *sec, unsigned long c,
|
||||
nb_elems = 1;
|
||||
if (gnu_ext && (l = is_label()) != 0)
|
||||
goto struct_field;
|
||||
s = type->ref;
|
||||
while (tok == '[' || tok == '.') {
|
||||
if (tok == '[') {
|
||||
if (!(type->t & VT_ARRAY))
|
||||
expect("array type");
|
||||
s = type->ref;
|
||||
next();
|
||||
index = expr_const();
|
||||
if (index < 0 || (s->c >= 0 && index >= s->c))
|
||||
@ -5077,7 +5078,6 @@ static void decl_designator(CType *type, Section *sec, unsigned long c,
|
||||
struct_field:
|
||||
if ((type->t & VT_BTYPE) != VT_STRUCT)
|
||||
expect("struct/union type");
|
||||
s = type->ref;
|
||||
l |= SYM_FIELD;
|
||||
f = s->next;
|
||||
while (f) {
|
||||
@ -5107,17 +5107,30 @@ static void decl_designator(CType *type, Section *sec, unsigned long c,
|
||||
} else {
|
||||
if (type->t & VT_ARRAY) {
|
||||
index = *cur_index;
|
||||
type = pointed_type(type);
|
||||
c += index * type_size(type, &align);
|
||||
if (s->c >= 0 && index >= s->c){
|
||||
if(!size_only)
|
||||
tcc_warning("excess elements in array initializer");
|
||||
type = NULL;
|
||||
size_only = 1;
|
||||
}else{
|
||||
type = pointed_type(type);
|
||||
c += index * type_size(type, &align);
|
||||
}
|
||||
} else {
|
||||
f = *cur_field;
|
||||
if (!f)
|
||||
tcc_error("too many field init");
|
||||
/* XXX: fix this mess by using explicit storage field */
|
||||
type1 = f->type;
|
||||
type1.t |= (type->t & ~VT_TYPE);
|
||||
type = &type1;
|
||||
c += f->c;
|
||||
if (f){
|
||||
/* XXX: fix this mess by using explicit storage field */
|
||||
type1 = f->type;
|
||||
type1.t |= (type->t & ~VT_TYPE);
|
||||
type = &type1;
|
||||
c += f->c;
|
||||
}else{
|
||||
if(!size_only)
|
||||
tcc_warning("excess elements in %s initializer",
|
||||
get_tok_str(s->type.t, NULL));
|
||||
type = NULL;
|
||||
size_only = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
decl_initializer(type, sec, c, 0, size_only);
|
||||
@ -5277,6 +5290,8 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||
Sym *s, *f;
|
||||
CType *t1;
|
||||
|
||||
if(!type)
|
||||
goto Ignore;
|
||||
if (type->t & VT_VLA) {
|
||||
int a;
|
||||
|
||||
@ -5367,14 +5382,10 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||
index = 0;
|
||||
while (tok != '}') {
|
||||
decl_designator(type, sec, c, &index, NULL, size_only);
|
||||
if (n >= 0 && index >= n)
|
||||
tcc_error("index too large");
|
||||
/* must put zero in holes (note that doing it that way
|
||||
ensures that it even works with designators) */
|
||||
if (!size_only && array_length < index) {
|
||||
init_putz(t1, sec, c + array_length * size1,
|
||||
(index - array_length) * size1);
|
||||
}
|
||||
if (!is_putz && array_length < index)
|
||||
is_putz = 1;
|
||||
index++;
|
||||
if (index > array_length)
|
||||
array_length = index;
|
||||
@ -5391,10 +5402,8 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||
if (!no_oblock)
|
||||
skip('}');
|
||||
/* put zeros at the end */
|
||||
if (!size_only && n >= 0 && array_length < n) {
|
||||
init_putz(t1, sec, c + array_length * size1,
|
||||
(n - array_length) * size1);
|
||||
}
|
||||
if (!is_putz && n >= 0 && array_length < n)
|
||||
is_putz = 1;
|
||||
/* patch type size if needed */
|
||||
if (n < 0)
|
||||
s->c = array_length;
|
||||
@ -5440,46 +5449,44 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||
n = s->c;
|
||||
while (tok != '}') {
|
||||
decl_designator(type, sec, c, NULL, &f, size_only);
|
||||
index = f->c;
|
||||
if (!size_only && array_length < index) {
|
||||
init_putz(type, sec, c + array_length,
|
||||
index - array_length);
|
||||
}
|
||||
index = index + type_size(&f->type, &align1);
|
||||
if (index > array_length)
|
||||
array_length = index;
|
||||
if(f){
|
||||
index = f->c;
|
||||
if (!is_putz && array_length < index)
|
||||
is_putz = 1;
|
||||
index = index + type_size(&f->type, &align1);
|
||||
if (index > array_length)
|
||||
array_length = index;
|
||||
|
||||
/* gr: skip fields from same union - ugly. */
|
||||
while (f->next) {
|
||||
///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
|
||||
/* test for same offset */
|
||||
if (f->next->c != f->c)
|
||||
break;
|
||||
/* if yes, test for bitfield shift */
|
||||
if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
|
||||
int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
|
||||
int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
|
||||
//printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
|
||||
if (bit_pos_1 != bit_pos_2)
|
||||
/* gr: skip fields from same union - ugly. */
|
||||
while (f->next) {
|
||||
///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
|
||||
/* test for same offset */
|
||||
if (f->next->c != f->c)
|
||||
break;
|
||||
/* if yes, test for bitfield shift */
|
||||
if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
|
||||
int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
|
||||
int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
|
||||
//printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
|
||||
if (bit_pos_1 != bit_pos_2)
|
||||
break;
|
||||
}
|
||||
f = f->next;
|
||||
}
|
||||
f = f->next;
|
||||
}
|
||||
|
||||
f = f->next;
|
||||
if (no_oblock && f == NULL)
|
||||
break;
|
||||
f = f->next;
|
||||
if (no_oblock && f == NULL)
|
||||
break;
|
||||
}
|
||||
if (tok == '}')
|
||||
break;
|
||||
skip(',');
|
||||
}
|
||||
/* put zeros at the end */
|
||||
if (!size_only && array_length < n) {
|
||||
init_putz(type, sec, c + array_length,
|
||||
n - array_length);
|
||||
}
|
||||
if (!no_oblock)
|
||||
skip('}');
|
||||
/* put zeros at the end */
|
||||
if (!is_putz && array_length < n)
|
||||
is_putz = 1;
|
||||
while (par_count) {
|
||||
skip(')');
|
||||
par_count--;
|
||||
@ -5489,6 +5496,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||
decl_initializer(type, sec, c, first, size_only);
|
||||
skip('}');
|
||||
} else if (size_only) {
|
||||
Ignore:
|
||||
/* just skip expression */
|
||||
parlevel = parlevel1 = 0;
|
||||
while ((parlevel > 0 || parlevel1 > 0 ||
|
||||
@ -5533,6 +5541,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||
Sym *flexible_array;
|
||||
|
||||
flexible_array = NULL;
|
||||
is_putz = 0;
|
||||
if ((type->t & VT_BTYPE) == VT_STRUCT) {
|
||||
Sym *field = type->ref->next;
|
||||
if (field) {
|
||||
@ -5551,7 +5560,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||
literals). It also simplifies local
|
||||
initializers handling */
|
||||
tok_str_new(&init_str);
|
||||
if (size < 0 || (flexible_array && has_init)) {
|
||||
if (size < 0 || ((((type->t & VT_BTYPE) == VT_STRUCT) || (type->t & VT_ARRAY)) &&
|
||||
has_init && (tok < TOK_IDENT))){
|
||||
if (!has_init)
|
||||
tcc_error("unknown type size");
|
||||
/* get all init string */
|
||||
@ -5742,6 +5752,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||
#endif
|
||||
}
|
||||
if (has_init || (type->t & VT_VLA)) {
|
||||
if(is_putz)
|
||||
init_putz(type, sec, addr, size);
|
||||
decl_initializer(type, sec, addr, 1, 0);
|
||||
/* restore parse state if needed */
|
||||
if (init_str.str) {
|
||||
|
Loading…
Reference in New Issue
Block a user