| @@ -74,7 +74,7 @@ static int is_compatible_types(CType *type1, CType *type2); · 73 unmodified lines |
| 74 | 74 | static int parse_btype(CType *type, AttributeDef *ad); |
| 75 | 75 | static void type_decl(CType *type, AttributeDef *ad, int *v, int td); |
| 76 | 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 | 78 | static void block(int *bsym, int *csym, int is_expr); |
| 79 | 79 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); |
| 80 | 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 | 5677 | /* t is the array or struct type. c is the array or struct |
| 5654 | 5678 | address. cur_index/cur_field is the pointer to the current |
| 5655 | 5679 | value. 'size_only' is true if only size info is needed (only used |
| 5656 | 5680 | in arrays) */ |
| 5657 | 5681 | static void decl_designator(CType *type, Section *sec, unsigned long c, |
| 5658 | 5682 | int *cur_index, Sym **cur_field, |
| 5659 | | − int size_only) |
| 5683 | + int size_only, int have_elem) |
| 5660 | 5684 | { |
| 5661 | 5685 | Sym *s, *f; |
| 5662 | 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 | 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 | 5777 | /* XXX: make it more general */ |
| 5754 | 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 | 5797 | /* store a value or an expression directly in global data or in local array */ |
| 5798 | 5798 | static void init_putv(CType *type, Section *sec, unsigned long c, |
| 5799 | 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 | 5957 | dimension implicit array init handling). 'size_only' is true if |
| 5958 | 5958 | size only evaluation is wanted (only for arrays). */ |
| 5959 | 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 | 5962 | int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i; |
| 5963 | 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 | 5979 | gen_vla_sp_save(c); |
| 5980 | 5980 | vla_sp_loc = c; |
| 5981 | 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 | 5989 | } else if (type->t & VT_ARRAY) { |
| 5983 | 5990 | s = type->ref; |
| 5984 | 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 | 6059 | } else { |
| 6053 | 6060 | index = 0; |
| 6054 | | − while (tok != '}') { |
| 6055 | | − decl_designator(type, sec, c, &index, NULL, size_only); |
| 6061 | + while (tok != '}' || have_elem) { |
| 6062 | + decl_designator(type, sec, c, &index, NULL, size_only, have_elem); |
| 6063 | + have_elem = 0; |
| 6056 | 6064 | if (n >= 0 && index >= n) |
| 6057 | 6065 | tcc_error("index too large"); |
| 6058 | 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 | 6092 | /* patch type size if needed */ |
| 6085 | 6093 | if (n < 0) |
| 6086 | 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 | 6100 | } else if ((type->t & VT_BTYPE) == VT_STRUCT && |
| 6088 | 6101 | (!first || tok == '{')) { |
| 6089 | 6102 | |
| @@ -6140,8 +6153,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 50 unmodified lines |
| 6140 | 6153 | array_length = 0; |
| 6141 | 6154 | index = 0; |
| 6142 | 6155 | n = s->c; |
| 6143 | | − while (tok != '}') { |
| 6144 | | − decl_designator(type, sec, c, NULL, &f, size_only); |
| 6156 | + while (tok != '}' || have_elem) { |
| 6157 | + decl_designator(type, sec, c, NULL, &f, size_only, have_elem); |
| 6158 | + have_elem = 0; |
| 6145 | 6159 | index = f->c; |
| 6146 | 6160 | if (!size_only && array_length < index) { |
| 6147 | 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 | 6223 | } else if (tok == '{') { |
| 6210 | 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 | 6228 | skip('}'); |
| 6213 | 6229 | } else if (size_only) { |
| 6214 | 6230 | /* just skip expression */ |
| @@ -6232,12 +6248,16 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 17 unmodified lines |
| 6232 | 6248 | next(); |
| 6233 | 6249 | } |
| 6234 | 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 | 6259 | /* currently, we always use constant expression for globals |
| 6236 | 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 | 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 | 6335 | begin_macro(init_str, 1); |
| 6316 | 6336 | next(); |
| 6317 | | − decl_initializer(type, NULL, 0, 1, 1); |
| 6337 | + decl_initializer(type, NULL, 0, 1, 1, 0); |
| 6318 | 6338 | /* prepare second initializer parsing */ |
| 6319 | 6339 | macro_ptr = init_str->str; |
| 6320 | 6340 | next(); |
| @@ -6473,7 +6493,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 152 unmodified lines |
| 6473 | 6493 | #endif |
| 6474 | 6494 | } |
| 6475 | 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 | 6497 | /* patch flexible array member size back to -1, */ |
| 6478 | 6498 | /* for possible subsequent similar declarations */ |
| 6479 | 6499 | if (flexible_array) |