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
5713 5713
5714/* t is the array or struct type. c is the array or struct5714/* t is the array or struct type. c is the array or struct
5715 address. cur_field is the pointer to the current5715 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).
5717 'size_only' is true if only size info is needed (only used5718 'size_only' is true if only size info is needed (only used
5718 in arrays) */5719 in arrays) */
5719static void decl_designator(CType *type, Section *sec, unsigned long c, 5720static 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
5748 index_last = index;5749 index_last = index;
5749 }5750 }
5750 skip(']');5751 skip(']');
5751 if (!notfirst)5752 if (!notfirst) {
5752 (*cur_field)->c = index_last;5753 (*cur_field)->c = index;
5754 (*cur_field)->r = index_last;
5755 }
5753 type = pointed_type(type);5756 type = pointed_type(type);
5754 elem_size = type_size(type, &align);5757 elem_size = type_size(type, &align);
5755 c += index * elem_size;5758 c += index * elem_size;
@@ -5812,17 +5815,25 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, · 56 unmodified lines
5812 uint8_t *src, *dst;5815 uint8_t *src, *dst;
5813 int i;5816 int i;
5814 5817
5815 if (!sec)5818 if (!sec) {
5816 tcc_error("range init not supported yet for dynamic storage");5819 vset(type, VT_LOCAL|VT_LVAL, c);
5817 c_end = c + nb_elems * elem_size;5820 for (i = 1; i < nb_elems; i++) {
5818 if (c_end > sec->data_allocated)5821 vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
5819 section_realloc(sec, c_end);5822 vswap();
5820 src = sec->data + c;5823 vstore();
5821 dst = src;5824 }
5822 for(i = 1; i < nb_elems; i++) {5825 vpop();
5823 dst += elem_size;5826 } else {
5824 memcpy(dst, src, elem_size);5827 c_end = c + nb_elems * elem_size;
5825 }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 }
5826 }5837 }
5827}5838}
5828 5839
@@ -6014,7 +6025,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 185 unmodified lines
6014 !(type->t & VT_ARRAY) &&6025 !(type->t & VT_ARRAY) &&
6015 /* Use i_c_parameter_t, to strip toplevel qualifiers.6026 /* Use i_c_parameter_t, to strip toplevel qualifiers.
6016 The source type might have VT_CONSTANT set, which is6027 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. */
6018 is_compatible_parameter_types(type, &vtop->type)) {6029 is_compatible_parameter_types(type, &vtop->type)) {
6019 init_putv(type, sec, c);6030 init_putv(type, sec, c);
6020 } else if (type->t & VT_ARRAY) {6031 } else if (type->t & VT_ARRAY) {
@@ -6088,6 +6099,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 67 unmodified lines
6088 }6099 }
6089 } else {6100 } else {
6090 indexsym.c = 0;6101 indexsym.c = 0;
6102 indexsym.r = 0;
6091 f = &indexsym;6103 f = &indexsym;
6092 6104
6093 do_init_list:6105 do_init_list:
@@ -6102,8 +6114,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 8 unmodified lines
6102 (index - array_length) * size1);6114 (index - array_length) * size1);
6103 }6115 }
6104 if (type->t & VT_ARRAY) {6116 if (type->t & VT_ARRAY) {
6105 index++;6117 index = indexsym.c = ++indexsym.r;
6106 indexsym.c++;
6107 } else {6118 } else {
6108 index = index + type_size(&f->type, &align1);6119 index = index + type_size(&f->type, &align1);
6109 if (s->type.t == TOK_UNION)6120 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
148 struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50};148 struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50};
149 const struct pkthdr *phdr = phdr_;149 const struct pkthdr *phdr = phdr_;
150 struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr };150 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 };
151 print(ls);154 print(ls);
152 print(ls2);155 print(ls2);
153 print(lt);156 print(lt);
@@ -163,6 +166,7 @@ void foo (struct W *w, struct pkthdr *phdr_) · 9 unmodified lines
163 print(lv);166 print(lv);
164 print(lv2);167 print(lv2);
165 print(lv3);168 print(lv3);
169 print(lt2);
166 print(flow);170 print(flow);
167}171}
168#endif172#endif
tests/tests2/86-struct-init.expect+1−0
@@ -33,4 +33,5 @@ ls3: 1 2 3 4 · 32 unmodified lines
33lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e33lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e
34lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 3034lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30
35lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3235lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32
36lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1
36flow: 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 037flow: 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