| @@ -81,6 +81,7 @@ ST_DATA int func_vc; · 80 unmodified lines |
| 81 | static int last_line_num, new_file, func_ind; /* debug info control */ | 81 | static int last_line_num, new_file, func_ind; /* debug info control */ |
| 82 | ST_DATA const char *funcname; | 82 | ST_DATA const char *funcname; |
| 83 | ST_DATA CType int_type, func_old_type, char_pointer_type; | 83 | ST_DATA CType int_type, func_old_type, char_pointer_type; |
| | 84 | static CString initstr; |
| 84 | | 85 | |
| 85 | #if PTR_SIZE == 4 | 86 | #if PTR_SIZE == 4 |
| 86 | #define VT_SIZE_T (VT_INT | VT_UNSIGNED) | 87 | #define VT_SIZE_T (VT_INT | VT_UNSIGNED) |
| @@ -779,6 +780,7 @@ ST_FUNC void tccgen_init(TCCState *s1) · 692 unmodified lines |
| 779 | #ifdef precedence_parser | 780 | #ifdef precedence_parser |
| 780 | init_prec(); | 781 | init_prec(); |
| 781 | #endif | 782 | #endif |
| | 783 | cstr_new(&initstr); |
| 782 | } | 784 | } |
| 783 | | 785 | |
| 784 | ST_FUNC int tccgen_compile(TCCState *s1) | 786 | ST_FUNC int tccgen_compile(TCCState *s1) |
| @@ -810,6 +812,7 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 25 unmodified lines |
| 810 | | 812 | |
| 811 | ST_FUNC void tccgen_finish(TCCState *s1) | 813 | ST_FUNC void tccgen_finish(TCCState *s1) |
| 812 | { | 814 | { |
| | 815 | cstr_free(&initstr); |
| 813 | free_inline_functions(s1); | 816 | free_inline_functions(s1); |
| 814 | sym_pop(&global_stack, NULL, 0); | 817 | sym_pop(&global_stack, NULL, 0); |
| 815 | sym_pop(&local_stack, NULL, 0); | 818 | sym_pop(&local_stack, NULL, 0); |
| @@ -3219,7 +3222,6 @@ redo: · 2403 unmodified lines |
| 3219 | gen_cast_s(VT_INT); | 3222 | gen_cast_s(VT_INT); |
| 3220 | #endif | 3223 | #endif |
| 3221 | type1 = vtop[-1].type; | 3224 | type1 = vtop[-1].type; |
| 3222 | type1.t &= ~VT_ARRAY; | | |
| 3223 | if (vtop[-1].type.t & VT_VLA) | 3225 | if (vtop[-1].type.t & VT_VLA) |
| 3224 | vla_runtime_pointed_size(&vtop[-1].type); | 3226 | vla_runtime_pointed_size(&vtop[-1].type); |
| 3225 | else { | 3227 | else { |
| @@ -3249,6 +3251,7 @@ redo: · 23 unmodified lines |
| 3249 | { | 3251 | { |
| 3250 | gen_opic(op); | 3252 | gen_opic(op); |
| 3251 | } | 3253 | } |
| | 3254 | type1.t &= ~VT_ARRAY; |
| 3252 | /* put again type if gen_opic() swaped operands */ | 3255 | /* put again type if gen_opic() swaped operands */ |
| 3253 | vtop->type = type1; | 3256 | vtop->type = type1; |
| 3254 | } | 3257 | } |
| @@ -7229,12 +7232,12 @@ static void parse_init_elem(int expr_type) · 3974 unmodified lines |
| 7229 | /* NOTE: symbols are accepted, as well as lvalue for anon symbols | 7232 | /* NOTE: symbols are accepted, as well as lvalue for anon symbols |
| 7230 | (compound literals). */ | 7233 | (compound literals). */ |
| 7231 | if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST | 7234 | if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST |
| 7232 | && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL) | 7235 | && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL) |
| 7233 | || vtop->sym->v < SYM_FIRST_ANOM)) | 7236 | || vtop->sym->v < SYM_FIRST_ANOM)) |
| 7234 | #ifdef TCC_TARGET_PE | 7237 | #ifdef TCC_TARGET_PE |
| 7235 | || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport) | 7238 | || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport) |
| 7236 | #endif | 7239 | #endif |
| 7237 | ) | 7240 | ) |
| 7238 | tcc_error("initializer element is not constant"); | 7241 | tcc_error("initializer element is not constant"); |
| 7239 | break; | 7242 | break; |
| 7240 | case EXPR_ANY: | 7243 | case EXPR_ANY: |
| @@ -7442,7 +7445,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 201 unmodified lines |
| 7442 | anonymous one. That is, there's no difference in vtop | 7445 | anonymous one. That is, there's no difference in vtop |
| 7443 | between '(void *){x}' and '&(void *){x}'. Ignore | 7446 | between '(void *){x}' and '&(void *){x}'. Ignore |
| 7444 | pointer typed entities here. Hopefully no real code | 7447 | pointer typed entities here. Hopefully no real code |
| 7445 | will every use compound literals with scalar type. */ | 7448 | will ever use compound literals with scalar type. */ |
| 7446 | (vtop->type.t & VT_BTYPE) != VT_PTR) { | 7449 | (vtop->type.t & VT_BTYPE) != VT_PTR) { |
| 7447 | /* These come from compound literals, memcpy stuff over. */ | 7450 | /* These come from compound literals, memcpy stuff over. */ |
| 7448 | Section *ssec; | 7451 | Section *ssec; |
| @@ -7450,7 +7453,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 1 unmodified line |
| 7450 | ElfW_Rel *rel; | 7453 | ElfW_Rel *rel; |
| 7451 | esym = elfsym(vtop->sym); | 7454 | esym = elfsym(vtop->sym); |
| 7452 | ssec = tcc_state->sections[esym->st_shndx]; | 7455 | ssec = tcc_state->sections[esym->st_shndx]; |
| 7453 | memmove (ptr, ssec->data + esym->st_value, size); | 7456 | memmove (ptr, ssec->data + esym->st_value + (int)vtop->c.i, size); |
| 7454 | if (ssec->reloc) { | 7457 | if (ssec->reloc) { |
| 7455 | /* We need to copy over all memory contents, and that | 7458 | /* We need to copy over all memory contents, and that |
| 7456 | includes relocations. Use the fact that relocs are | 7459 | includes relocations. Use the fact that relocs are |
| @@ -7593,7 +7596,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 136 unmodified lines |
| 7593 | static void decl_initializer(CType *type, Section *sec, unsigned long c, | 7596 | static void decl_initializer(CType *type, Section *sec, unsigned long c, |
| 7594 | int flags) | 7597 | int flags) |
| 7595 | { | 7598 | { |
| 7596 | int len, n, no_oblock, nb, i; | 7599 | int len, n, no_oblock, i; |
| 7597 | int size1, align1; | 7600 | int size1, align1; |
| 7598 | Sym *s, *f; | 7601 | Sym *s, *f; |
| 7599 | Sym indexsym; | 7602 | Sym indexsym; |
| @@ -7641,41 +7644,54 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 41 unmodified lines |
| 7641 | (t1->t & VT_BTYPE) == VT_INT | 7644 | (t1->t & VT_BTYPE) == VT_INT |
| 7642 | #endif | 7645 | #endif |
| 7643 | ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) { | 7646 | ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) { |
| | 7647 | int nb; |
| 7644 | len = 0; | 7648 | len = 0; |
| | 7649 | cstr_reset(&initstr); |
| | 7650 | if (size1 != (tok == TOK_STR ? 1 : sizeof(nwchar_t))) |
| | 7651 | tcc_error("unhandled string literal merging"); |
| 7645 | while (tok == TOK_STR || tok == TOK_LSTR) { | 7652 | while (tok == TOK_STR || tok == TOK_LSTR) { |
| 7646 | int cstr_len, ch; | 7653 | if (initstr.size) |
| 7647 | | 7654 | initstr.size -= size1; |
| 7648 | /* compute maximum number of chars wanted */ | | |
| 7649 | if (tok == TOK_STR) | 7655 | if (tok == TOK_STR) |
| 7650 | cstr_len = tokc.str.size; | 7656 | len += tokc.str.size; |
| 7651 | else | 7657 | else |
| 7652 | cstr_len = tokc.str.size / sizeof(nwchar_t); | 7658 | len += tokc.str.size / sizeof(nwchar_t); |
| 7653 | cstr_len--; | 7659 | len--; |
| 7654 | nb = cstr_len; | 7660 | cstr_cat(&initstr, tokc.str.data, tokc.str.size); |
| 7655 | if (n >= 0 && nb > (n - len)) | 7661 | next(); |
| 7656 | nb = n - len; | 7662 | } |
| 7657 | if (!(flags & DIF_SIZE_ONLY)) { | 7663 | if (tok != ')' && tok != '}' && tok != ',' && tok != ';' |
| 7658 | if (cstr_len > nb) | 7664 | && tok != TOK_EOF) { |
| 7659 | tcc_warning("initializer-string for array is too long"); | 7665 | /* Not a lone literal but part of a bigger expression. */ |
| 7660 | /* in order to go faster for common case (char | 7666 | unget_tok(size1 == 1 ? TOK_STR : TOK_LSTR); |
| 7661 | string in global variable, we handle it | 7667 | tokc.str.size = initstr.size; |
| 7662 | specifically */ | 7668 | tokc.str.data = initstr.data; |
| 7663 | if (sec && tok == TOK_STR && size1 == 1) { | 7669 | indexsym.c = 0; |
| 7664 | if (!NODATA_WANTED) | 7670 | f = &indexsym; |
| 7665 | memcpy(sec->data + c + len, tokc.str.data, nb); | 7671 | goto do_init_list; |
| 7666 | } else { | 7672 | } |
| 7667 | for(i=0;i<nb;i++) { | 7673 | nb = len; |
| 7668 | if (tok == TOK_STR) | 7674 | if (n >= 0 && len > n) |
| 7669 | ch = ((unsigned char *)tokc.str.data)[i]; | 7675 | nb = n; |
| 7670 | else | 7676 | if (!(flags & DIF_SIZE_ONLY)) { |
| 7671 | ch = ((nwchar_t *)tokc.str.data)[i]; | 7677 | if (len > nb) |
| 7672 | vpushi(ch); | 7678 | tcc_warning("initializer-string for array is too long"); |
| 7673 | init_putv(t1, sec, c + (len + i) * size1); | 7679 | /* in order to go faster for common case (char |
| 7674 | } | 7680 | string in global variable, we handle it |
| | 7681 | specifically */ |
| | 7682 | if (sec && size1 == 1) { |
| | 7683 | if (!NODATA_WANTED) |
| | 7684 | memcpy(sec->data + c, initstr.data, nb); |
| | 7685 | } else { |
| | 7686 | for(i=0;i<nb;i++) { |
| | 7687 | if (size1 == 1) |
| | 7688 | ch = ((unsigned char *)initstr.data)[i]; |
| | 7689 | else |
| | 7690 | ch = ((nwchar_t *)initstr.data)[i]; |
| | 7691 | vpushi(ch); |
| | 7692 | init_putv(t1, sec, c + i * size1); |
| 7675 | } | 7693 | } |
| 7676 | } | 7694 | } |
| 7677 | len += nb; | | |
| 7678 | next(); | | |
| 7679 | } | 7695 | } |
| 7680 | /* only add trailing zero if enough storage (no | 7696 | /* only add trailing zero if enough storage (no |
| 7681 | warning in this case since it is standard) */ | 7697 | warning in this case since it is standard) */ |