| @@ -74,7 +74,7 @@ static int is_compatible_types(CType *type1, CType *type2); · 73 unmodified lines |
| 74 | static int parse_btype(CType *type, AttributeDef *ad); | 74 | static int parse_btype(CType *type, AttributeDef *ad); |
| 75 | static void type_decl(CType *type, AttributeDef *ad, int *v, int td); | 75 | static void type_decl(CType *type, AttributeDef *ad, int *v, int td); |
| 76 | static void parse_expr_type(CType *type); | 76 | static void parse_expr_type(CType *type); |
| 77 | static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); | 77 | static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only, int have_elem); |
| 78 | static void block(int *bsym, int *csym, int is_expr); | 78 | static void block(int *bsym, int *csym, int is_expr); |
| 79 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); | 79 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); |
| 80 | static int decl0(int l, int is_for_loop_init); | 80 | static int decl0(int l, int is_for_loop_init); |
| @@ -5650,13 +5650,37 @@ static void block(int *bsym, int *csym, int is_expr) · 5569 unmodified lines |
| 5650 | } | 5650 | } |
| 5651 | } | 5651 | } |
| 5652 | | 5652 | |
| | 5653 | #define EXPR_VAL 0 |
| | 5654 | #define EXPR_CONST 1 |
| | 5655 | #define EXPR_ANY 2 |
| | 5656 | |
| | 5657 | static void parse_init_elem(int expr_type) |
| | 5658 | { |
| | 5659 | int saved_global_expr; |
| | 5660 | switch(expr_type) { |
| | 5661 | case EXPR_CONST: |
| | 5662 | /* compound literals must be allocated globally in this case */ |
| | 5663 | saved_global_expr = global_expr; |
| | 5664 | global_expr = 1; |
| | 5665 | expr_const1(); |
| | 5666 | global_expr = saved_global_expr; |
| | 5667 | /* NOTE: symbols are accepted */ |
| | 5668 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST) |
| | 5669 | tcc_error("initializer element is not constant"); |
| | 5670 | break; |
| | 5671 | case EXPR_ANY: |
| | 5672 | expr_eq(); |
| | 5673 | break; |
| | 5674 | } |
| | 5675 | } |
| | 5676 | |
| 5653 | /* t is the array or struct type. c is the array or struct | 5677 | /* t is the array or struct type. c is the array or struct |
| 5654 | address. cur_index/cur_field is the pointer to the current | 5678 | address. cur_index/cur_field is the pointer to the current |
| 5655 | value. 'size_only' is true if only size info is needed (only used | 5679 | value. 'size_only' is true if only size info is needed (only used |
| 5656 | in arrays) */ | 5680 | in arrays) */ |
| 5657 | static void decl_designator(CType *type, Section *sec, unsigned long c, | 5681 | static void decl_designator(CType *type, Section *sec, unsigned long c, |
| 5658 | int *cur_index, Sym **cur_field, | 5682 | int *cur_index, Sym **cur_field, |
| 5659 | int size_only) | 5683 | int size_only, int have_elem) |
| 5660 | { | 5684 | { |
| 5661 | Sym *s, *f; | 5685 | Sym *s, *f; |
| 5662 | int notfirst, index, index_last, align, l, nb_elems, elem_size; | 5686 | int notfirst, index, index_last, align, l, nb_elems, elem_size; |
| @@ -5748,7 +5772,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, · 85 unmodified lines |
| 5748 | c += f->c; | 5772 | c += f->c; |
| 5749 | } | 5773 | } |
| 5750 | } | 5774 | } |
| 5751 | decl_initializer(type, sec, c, 0, size_only); | 5775 | decl_initializer(type, sec, c, 0, size_only, have_elem); |
| 5752 | | 5776 | |
| 5753 | /* XXX: make it more general */ | 5777 | /* XXX: make it more general */ |
| 5754 | if (!size_only && nb_elems > 1) { | 5778 | if (!size_only && nb_elems > 1) { |
| @@ -5770,30 +5794,6 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, · 15 unmodified lines |
| 5770 | } | 5794 | } |
| 5771 | } | 5795 | } |
| 5772 | | 5796 | |
| 5773 | #define EXPR_VAL 0 | | |
| 5774 | #define EXPR_CONST 1 | | |
| 5775 | #define EXPR_ANY 2 | | |
| 5776 | | | |
| 5777 | static void parse_init_elem(int expr_type) | | |
| 5778 | { | | |
| 5779 | int saved_global_expr; | | |
| 5780 | switch(expr_type) { | | |
| 5781 | case EXPR_CONST: | | |
| 5782 | /* compound literals must be allocated globally in this case */ | | |
| 5783 | saved_global_expr = global_expr; | | |
| 5784 | global_expr = 1; | | |
| 5785 | expr_const1(); | | |
| 5786 | global_expr = saved_global_expr; | | |
| 5787 | /* NOTE: symbols are accepted */ | | |
| 5788 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST) | | |
| 5789 | tcc_error("initializer element is not constant"); | | |
| 5790 | break; | | |
| 5791 | case EXPR_ANY: | | |
| 5792 | expr_eq(); | | |
| 5793 | break; | | |
| 5794 | } | | |
| 5795 | } | | |
| 5796 | | | |
| 5797 | /* store a value or an expression directly in global data or in local array */ | 5797 | /* store a value or an expression directly in global data or in local array */ |
| 5798 | static void init_putv(CType *type, Section *sec, unsigned long c, | 5798 | static void init_putv(CType *type, Section *sec, unsigned long c, |
| 5799 | int v, int expr_type) | 5799 | int v, int expr_type) |
| @@ -5957,7 +5957,7 @@ static void init_putz(CType *t, Section *sec, unsigned long c, int size) · 157 unmodified lines |
| 5957 | dimension implicit array init handling). 'size_only' is true if | 5957 | dimension implicit array init handling). 'size_only' is true if |
| 5958 | size only evaluation is wanted (only for arrays). */ | 5958 | size only evaluation is wanted (only for arrays). */ |
| 5959 | static void decl_initializer(CType *type, Section *sec, unsigned long c, | 5959 | static void decl_initializer(CType *type, Section *sec, unsigned long c, |
| 5960 | int first, int size_only) | 5960 | int first, int size_only, int have_elem) |
| 5961 | { | 5961 | { |
| 5962 | int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i; | 5962 | int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i; |
| 5963 | int size1, align1, expr_type; | 5963 | int size1, align1, expr_type; |
| @@ -5979,6 +5979,13 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 15 unmodified lines |
| 5979 | gen_vla_sp_save(c); | 5979 | gen_vla_sp_save(c); |
| 5980 | vla_sp_loc = c; | 5980 | vla_sp_loc = c; |
| 5981 | vlas_in_scope++; | 5981 | vlas_in_scope++; |
| | 5982 | } else if (!have_elem && tok != '{' && tok != TOK_LSTR && |
| | 5983 | tok != TOK_STR && !size_only) { |
| | 5984 | parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST); |
| | 5985 | have_elem = 1; |
| | 5986 | } |
| | 5987 | |
| | 5988 | if (type->t & VT_VLA) { |
| 5982 | } else if (type->t & VT_ARRAY) { | 5989 | } else if (type->t & VT_ARRAY) { |
| 5983 | s = type->ref; | 5990 | s = type->ref; |
| 5984 | n = s->c; | 5991 | n = s->c; |
| @@ -6051,8 +6058,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 66 unmodified lines |
| 6051 | } | 6058 | } |
| 6052 | } else { | 6059 | } else { |
| 6053 | index = 0; | 6060 | index = 0; |
| 6054 | while (tok != '}') { | 6061 | while (tok != '}' || have_elem) { |
| 6055 | decl_designator(type, sec, c, &index, NULL, size_only); | 6062 | decl_designator(type, sec, c, &index, NULL, size_only, have_elem); |
| | 6063 | have_elem = 0; |
| 6056 | if (n >= 0 && index >= n) | 6064 | if (n >= 0 && index >= n) |
| 6057 | tcc_error("index too large"); | 6065 | tcc_error("index too large"); |
| 6058 | /* must put zero in holes (note that doing it that way | 6066 | /* must put zero in holes (note that doing it that way |
| @@ -6084,6 +6092,11 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 25 unmodified lines |
| 6084 | /* patch type size if needed */ | 6092 | /* patch type size if needed */ |
| 6085 | if (n < 0) | 6093 | if (n < 0) |
| 6086 | s->c = array_length; | 6094 | s->c = array_length; |
| | 6095 | } else if (1 && have_elem && is_compatible_types(type, &vtop->type)) { |
| | 6096 | /* currently, we always use constant expression for globals |
| | 6097 | (may change for scripting case) */ |
| | 6098 | expr_type = !sec ? EXPR_ANY : EXPR_CONST; |
| | 6099 | init_putv(type, sec, c, 0, expr_type); |
| 6087 | } else if ((type->t & VT_BTYPE) == VT_STRUCT && | 6100 | } else if ((type->t & VT_BTYPE) == VT_STRUCT && |
| 6088 | (!first || tok == '{')) { | 6101 | (!first || tok == '{')) { |
| 6089 | | 6102 | |
| @@ -6140,8 +6153,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 50 unmodified lines |
| 6140 | array_length = 0; | 6153 | array_length = 0; |
| 6141 | index = 0; | 6154 | index = 0; |
| 6142 | n = s->c; | 6155 | n = s->c; |
| 6143 | while (tok != '}') { | 6156 | while (tok != '}' || have_elem) { |
| 6144 | decl_designator(type, sec, c, NULL, &f, size_only); | 6157 | decl_designator(type, sec, c, NULL, &f, size_only, have_elem); |
| | 6158 | have_elem = 0; |
| 6145 | index = f->c; | 6159 | index = f->c; |
| 6146 | if (!size_only && array_length < index) { | 6160 | if (!size_only && array_length < index) { |
| 6147 | init_putz(type, sec, c + array_length, | 6161 | init_putz(type, sec, c + array_length, |
| @@ -6208,7 +6222,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 60 unmodified lines |
| 6208 | } | 6222 | } |
| 6209 | } else if (tok == '{') { | 6223 | } else if (tok == '{') { |
| 6210 | next(); | 6224 | next(); |
| 6211 | decl_initializer(type, sec, c, first, size_only); | 6225 | if (have_elem) |
| | 6226 | tcc_error("shouldn't have parsed init element"); |
| | 6227 | decl_initializer(type, sec, c, first, size_only, 0); |
| 6212 | skip('}'); | 6228 | skip('}'); |
| 6213 | } else if (size_only) { | 6229 | } else if (size_only) { |
| 6214 | /* just skip expression */ | 6230 | /* just skip expression */ |
| @@ -6232,12 +6248,16 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 17 unmodified lines |
| 6232 | next(); | 6248 | next(); |
| 6233 | } | 6249 | } |
| 6234 | } else { | 6250 | } else { |
| | 6251 | if (!have_elem) { |
| | 6252 | /* This should happen only when we haven't parsed |
| | 6253 | the init element above for fear of committing a |
| | 6254 | string constant to memory too early. */ |
| | 6255 | if (tok != TOK_STR && tok != TOK_LSTR) |
| | 6256 | expect("string constant"); |
| | 6257 | parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST); |
| | 6258 | } |
| 6235 | /* currently, we always use constant expression for globals | 6259 | /* currently, we always use constant expression for globals |
| 6236 | (may change for scripting case) */ | 6260 | (may change for scripting case) */ |
| 6237 | expr_type = EXPR_CONST; | | |
| 6238 | if (!sec) | | |
| 6239 | expr_type = EXPR_ANY; | | |
| 6240 | parse_init_elem(expr_type); | | |
| 6241 | init_putv(type, sec, c, 0, expr_type); | 6261 | init_putv(type, sec, c, 0, expr_type); |
| 6242 | } | 6262 | } |
| 6243 | } | 6263 | } |
| @@ -6314,7 +6334,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 70 unmodified lines |
| 6314 | | 6334 | |
| 6315 | begin_macro(init_str, 1); | 6335 | begin_macro(init_str, 1); |
| 6316 | next(); | 6336 | next(); |
| 6317 | decl_initializer(type, NULL, 0, 1, 1); | 6337 | decl_initializer(type, NULL, 0, 1, 1, 0); |
| 6318 | /* prepare second initializer parsing */ | 6338 | /* prepare second initializer parsing */ |
| 6319 | macro_ptr = init_str->str; | 6339 | macro_ptr = init_str->str; |
| 6320 | next(); | 6340 | next(); |
| @@ -6473,7 +6493,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 152 unmodified lines |
| 6473 | #endif | 6493 | #endif |
| 6474 | } | 6494 | } |
| 6475 | if (has_init || (type->t & VT_VLA)) { | 6495 | if (has_init || (type->t & VT_VLA)) { |
| 6476 | decl_initializer(type, sec, addr, 1, 0); | 6496 | decl_initializer(type, sec, addr, 1, 0, 0); |
| 6477 | /* patch flexible array member size back to -1, */ | 6497 | /* patch flexible array member size back to -1, */ |
| 6478 | /* for possible subsequent similar declarations */ | 6498 | /* for possible subsequent similar declarations */ |
| 6479 | if (flexible_array) | 6499 | if (flexible_array) |