From: jiang <30155751@qq.com> Date: Wed, 28 May 2014 14:09:49 +0000 (+0800) Subject: Let init_putz one-time generation. X-Git-Tag: release_0_9_27~874^2~3 X-Git-Url: https://repo.or.cz/w/tinycc.git/commitdiff_plain/d316836008f4738d5a020b28aa33e96a82a81aca 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
: 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 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 65: b8 00 00 00 00 mov $0x0,%eax 6a: e9 00 00 00 00 jmpq 6f 6f: c9 leaveq 70: c3 retq After the patch 0000000000000000
: 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 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 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 --- diff --git a/tccgen.c b/tccgen.c index d286dd47..b2a77178 100644 --- a/tccgen.c +++ b/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; - - /* 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) + 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) + break; + } + 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) {