History

struct-init: Support range inits for local vars

Implement missing support for range init for local variables.

Michael Matz committed 10 years ago

Commit 4e46c221 parent 4cb70473 files · +33 −17Browse files

Unified · Split

3 files
  1. tccgen.c +28 −17
  2. tests/tests2/86-struct-init.c +4 −0
  3. tests/tests2/86-struct-init.expect +1 −0
tccgen.c+28−17
@@ -5713,7 +5713,8 @@ static void parse_init_elem(int expr_type) · 5712 unmodified lines
57135713
57145714 /* t is the array or struct type. c is the array or struct
57155715 address. cur_field is the pointer to the current
5716− value, for arrays the 'c' member contains the current index.
5716+ value, for arrays the 'c' member contains the current start
5717+ index and the 'r' contains the end index (in case of range init).
57175718 'size_only' is true if only size info is needed (only used
57185719 in arrays) */
57195720 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, · 28 unmodified lines
57485749 index_last = index;
57495750 }
57505751 skip(']');
5751− if (!notfirst)
5752− (*cur_field)->c = index_last;
5752+ if (!notfirst) {
5753+ (*cur_field)->c = index;
5754+ (*cur_field)->r = index_last;
5755+ }
57535756 type = pointed_type(type);
57545757 elem_size = type_size(type, &align);
57555758 c += index * elem_size;
@@ -5812,17 +5815,25 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, · 56 unmodified lines
58125815 uint8_t *src, *dst;
58135816 int i;
58145817
5815− if (!sec)
5816− tcc_error("range init not supported yet for dynamic storage");
5817− c_end = c + nb_elems * elem_size;
5818− if (c_end > sec->data_allocated)
5819− section_realloc(sec, c_end);
5820− src = sec->data + c;
5821− dst = src;
5822− for(i = 1; i < nb_elems; i++) {
5823− dst += elem_size;
5824− memcpy(dst, src, elem_size);
5825− }
5818+ if (!sec) {
5819+ vset(type, VT_LOCAL|VT_LVAL, c);
5820+ for (i = 1; i < nb_elems; i++) {
5821+ vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
5822+ vswap();
5823+ vstore();
5824+ }
5825+ vpop();
5826+ } else {
5827+ c_end = c + nb_elems * elem_size;
5828+ if (c_end > sec->data_allocated)
5829+ section_realloc(sec, c_end);
5830+ src = sec->data + c;
5831+ dst = src;
5832+ for(i = 1; i < nb_elems; i++) {
5833+ dst += elem_size;
5834+ memcpy(dst, src, elem_size);
5835+ }
5836+ }
58265837 }
58275838 }
58285839
@@ -6014,7 +6025,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 185 unmodified lines
60146025 !(type->t & VT_ARRAY) &&
60156026 /* Use i_c_parameter_t, to strip toplevel qualifiers.
60166027 The source type might have VT_CONSTANT set, which is
6017− of course assignable to a non-const elements. */
6028+ of course assignable to non-const elements. */
60186029 is_compatible_parameter_types(type, &vtop->type)) {
60196030 init_putv(type, sec, c);
60206031 } else if (type->t & VT_ARRAY) {
@@ -6088,6 +6099,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 67 unmodified lines
60886099 }
60896100 } else {
60906101 indexsym.c = 0;
6102+ indexsym.r = 0;
60916103 f = &indexsym;
60926104
60936105 do_init_list:
@@ -6102,8 +6114,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 8 unmodified lines
61026114 (index - array_length) * size1);
61036115 }
61046116 if (type->t & VT_ARRAY) {
6105− index++;
6106− indexsym.c++;
6117+ index = indexsym.c = ++indexsym.r;
61076118 } else {
61086119 index = index + type_size(&f->type, &align1);
61096120 if (s->type.t == TOK_UNION)
tests/tests2/86-struct-init.c+4−0
@@ -148,6 +148,9 @@ void foo (struct W *w, struct pkthdr *phdr_) · 147 unmodified lines
148148 struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50};
149149 const struct pkthdr *phdr = phdr_;
150150 struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr };
151+ int elt = 0x42;
152+ /* Range init, overlapping */
153+ struct T lt2 = { { [1 ... 5] = 9, [6 ... 10] = elt, [4 ... 7] = elt+1 }, 1 };
151154 print(ls);
152155 print(ls2);
153156 print(lt);
@@ -163,6 +166,7 @@ void foo (struct W *w, struct pkthdr *phdr_) · 9 unmodified lines
163166 print(lv);
164167 print(lv2);
165168 print(lv3);
169+ print(lt2);
166170 print(flow);
167171 }
168172 #endif
tests/tests2/86-struct-init.expect+1−0
@@ -33,4 +33,5 @@ ls3: 1 2 3 4 · 32 unmodified lines
3333 lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e
3434 lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30
3535 lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32
36+lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1
3637 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