From 4e46c22d5ca4d03220e30fa524a5aba4b4df75f9 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sat, 6 Aug 2016 22:38:26 +0200 Subject: [PATCH] struct-init: Support range inits for local vars Implement missing support for range init for local variables. --- tccgen.c | 45 +++++++++++++++++++----------- tests/tests2/86-struct-init.c | 4 +++ tests/tests2/86-struct-init.expect | 1 + 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/tccgen.c b/tccgen.c index a833b177..aafea362 100644 --- a/tccgen.c +++ b/tccgen.c @@ -5713,7 +5713,8 @@ static void parse_init_elem(int expr_type) /* t is the array or struct type. c is the array or struct address. cur_field is the pointer to the current - value, for arrays the 'c' member contains the current index. + value, for arrays the 'c' member contains the current start + index and the 'r' contains the end index (in case of range init). 'size_only' is true if only size info is needed (only used in arrays) */ static void decl_designator(CType *type, Section *sec, unsigned long c, @@ -5748,8 +5749,10 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, index_last = index; } skip(']'); - if (!notfirst) - (*cur_field)->c = index_last; + if (!notfirst) { + (*cur_field)->c = index; + (*cur_field)->r = index_last; + } type = pointed_type(type); elem_size = type_size(type, &align); c += index * elem_size; @@ -5812,17 +5815,25 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, uint8_t *src, *dst; int i; - if (!sec) - tcc_error("range init not supported yet for dynamic storage"); - c_end = c + nb_elems * elem_size; - if (c_end > sec->data_allocated) - section_realloc(sec, c_end); - src = sec->data + c; - dst = src; - for(i = 1; i < nb_elems; i++) { - dst += elem_size; - memcpy(dst, src, elem_size); - } + if (!sec) { + vset(type, VT_LOCAL|VT_LVAL, c); + for (i = 1; i < nb_elems; i++) { + vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i); + vswap(); + vstore(); + } + vpop(); + } else { + c_end = c + nb_elems * elem_size; + if (c_end > sec->data_allocated) + section_realloc(sec, c_end); + src = sec->data + c; + dst = src; + for(i = 1; i < nb_elems; i++) { + dst += elem_size; + memcpy(dst, src, elem_size); + } + } } } @@ -6014,7 +6025,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, !(type->t & VT_ARRAY) && /* Use i_c_parameter_t, to strip toplevel qualifiers. The source type might have VT_CONSTANT set, which is - of course assignable to a non-const elements. */ + of course assignable to non-const elements. */ is_compatible_parameter_types(type, &vtop->type)) { init_putv(type, sec, c); } else if (type->t & VT_ARRAY) { @@ -6088,6 +6099,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, } } else { indexsym.c = 0; + indexsym.r = 0; f = &indexsym; do_init_list: @@ -6102,8 +6114,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, (index - array_length) * size1); } if (type->t & VT_ARRAY) { - index++; - indexsym.c++; + index = indexsym.c = ++indexsym.r; } else { index = index + type_size(&f->type, &align1); if (s->type.t == TOK_UNION) diff --git a/tests/tests2/86-struct-init.c b/tests/tests2/86-struct-init.c index 6ce4e24b..3cf25c73 100644 --- a/tests/tests2/86-struct-init.c +++ b/tests/tests2/86-struct-init.c @@ -148,6 +148,9 @@ void foo (struct W *w, struct pkthdr *phdr_) struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50}; const struct pkthdr *phdr = phdr_; struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr }; + int elt = 0x42; + /* Range init, overlapping */ + struct T lt2 = { { [1 ... 5] = 9, [6 ... 10] = elt, [4 ... 7] = elt+1 }, 1 }; print(ls); print(ls2); print(lt); @@ -163,6 +166,7 @@ void foo (struct W *w, struct pkthdr *phdr_) print(lv); print(lv2); print(lv3); + print(lt2); print(flow); } #endif diff --git a/tests/tests2/86-struct-init.expect b/tests/tests2/86-struct-init.expect index b827ec45..1498a3d3 100644 --- a/tests/tests2/86-struct-init.expect +++ b/tests/tests2/86-struct-init.expect @@ -33,4 +33,5 @@ ls3: 1 2 3 4 lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30 lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 +lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1 flow: 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0