diff options
| author | jiang <30155751@qq.com> | 2014-05-28 22:09:49 +0800 |
|---|---|---|
| committer | jiang <30155751@qq.com> | 2014-05-28 22:09:49 +0800 |
| commit | d316836008f4738d5a020b28aa33e96a82a81aca (patch) | |
| tree | 81587e8c90b3c4f6c4c4e5d379ab37c30fb9c4af | |
| parent | 89134dd7b021389331d91e0552babf6de5108588 (diff) | |
| download | tinycc-d316836008f4738d5a020b28aa33e96a82a81aca.tar.gz tinycc-d316836008f4738d5a020b28aa33e96a82a81aca.tar.bz2 | |
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
| -rw-r--r-- | tccgen.c | 114 |
1 files changed, 63 insertions, 51 deletions
@@ -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; + 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) { |
