Start reimplementing the whole initializer handling to be conforming to ISO C. This patch just reimplements current functionality to prepare for further changes, all tests pass.
Unified · Split
| @@ -5774,19 +5774,10 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, · 5773 unmodified lines | |||
| 5774 | #define EXPR_CONST 1 | 5774 | #define EXPR_CONST 1 |
| 5775 | #define EXPR_ANY 2 | 5775 | #define EXPR_ANY 2 |
| 5776 | 5776 | ||
| 5777 | /* store a value or an expression directly in global data or in local array */ | 5777 | static void parse_init_elem(int expr_type) |
| 5778 | static void init_putv(CType *type, Section *sec, unsigned long c, | ||
| 5779 | int v, int expr_type) | ||
| 5780 | { | 5778 | { |
| 5781 | int saved_global_expr, bt, bit_pos, bit_size; | 5779 | int saved_global_expr; |
| 5782 | void *ptr; | ||
| 5783 | unsigned long long bit_mask; | ||
| 5784 | CType dtype; | ||
| 5785 | |||
| 5786 | switch(expr_type) { | 5780 | switch(expr_type) { |
| 5787 | case EXPR_VAL: | ||
| 5788 | vpushi(v); | ||
| 5789 | break; | ||
| 5790 | case EXPR_CONST: | 5781 | case EXPR_CONST: |
| 5791 | /* compound literals must be allocated globally in this case */ | 5782 | /* compound literals must be allocated globally in this case */ |
| 5792 | saved_global_expr = global_expr; | 5783 | saved_global_expr = global_expr; |
| @@ -5801,18 +5792,29 @@ static void init_putv(CType *type, Section *sec, unsigned long c, · 8 unmodified lines | |||
| 5801 | expr_eq(); | 5792 | expr_eq(); |
| 5802 | break; | 5793 | break; |
| 5803 | } | 5794 | } |
| 5804 | 5795 | } | |
| 5796 | |||
| 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, | ||
| 5799 | int v, int expr_type) | ||
| 5800 | { | ||
| 5801 | int bt, bit_pos, bit_size; | ||
| 5802 | void *ptr; | ||
| 5803 | unsigned long long bit_mask; | ||
| 5804 | CType dtype; | ||
| 5805 | |||
| 5805 | dtype = *type; | 5806 | dtype = *type; |
| 5806 | dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ | 5807 | dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ |
| 5807 | 5808 | ||
| 5808 | if (sec) { | 5809 | if (sec) { |
| 5810 | int size, align; | ||
| 5809 | /* XXX: not portable */ | 5811 | /* XXX: not portable */ |
| 5810 | /* XXX: generate error if incorrect relocation */ | 5812 | /* XXX: generate error if incorrect relocation */ |
| 5811 | gen_assign_cast(&dtype); | 5813 | gen_assign_cast(&dtype); |
| 5812 | bt = type->t & VT_BTYPE; | 5814 | bt = type->t & VT_BTYPE; |
| 5813 | /* we'll write at most 16 bytes */ | 5815 | size = type_size(type, &align); |
| 5814 | if (c + 16 > sec->data_allocated) { | 5816 | if (c + size > sec->data_allocated) { |
| 5815 | section_realloc(sec, c + 16); | 5817 | section_realloc(sec, c + size); |
| 5816 | } | 5818 | } |
| 5817 | ptr = sec->data + c; | 5819 | ptr = sec->data + c; |
| 5818 | /* XXX: make code faster ? */ | 5820 | /* XXX: make code faster ? */ |
| @@ -5825,79 +5827,102 @@ static void init_putv(CType *type, Section *sec, unsigned long c, · 6 unmodified lines | |||
| 5825 | bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; | 5827 | bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; |
| 5826 | bit_mask = (1LL << bit_size) - 1; | 5828 | bit_mask = (1LL << bit_size) - 1; |
| 5827 | } | 5829 | } |
| 5828 | if ((vtop->r & VT_SYM) && | 5830 | if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) && |
| 5829 | (bt == VT_BYTE || | 5831 | vtop->sym->v >= SYM_FIRST_ANOM && |
| 5830 | bt == VT_SHORT || | 5832 | /* XXX This rejects compount literals like |
| 5831 | bt == VT_DOUBLE || | 5833 | '(void *){ptr}'. The problem is that '&sym' is |
| 5832 | bt == VT_LDOUBLE || | 5834 | represented the same way, which would be ruled out |
| 5835 | by the SYM_FIRST_ANOM check above, but also '"string"' | ||
| 5836 | in 'char *p = "string"' is represented the same | ||
| 5837 | with the type being VT_PTR and the symbol being an | ||
| 5838 | anonymous one. That is, there's no difference in vtop | ||
| 5839 | between '(void *){x}' and '&(void *){x}'. Ignore | ||
| 5840 | pointer typed entities here. Hopefully no real code | ||
| 5841 | will every use compound literals with scalar type. */ | ||
| 5842 | (vtop->type.t & VT_BTYPE) != VT_PTR) { | ||
| 5843 | /* These come from compound literals, memcpy stuff over. */ | ||
| 5844 | Section *ssec; | ||
| 5845 | ElfW(Sym) *esym; | ||
| 5846 | esym = &((ElfW(Sym) *)symtab_section->data)[vtop->sym->c]; | ||
| 5847 | ssec = tcc_state->sections[esym->st_shndx]; | ||
| 5848 | memmove (ptr, ssec->data + esym->st_value, size); | ||
| 5849 | } else { | ||
| 5850 | if ((vtop->r & VT_SYM) && | ||
| 5851 | (bt == VT_BYTE || | ||
| 5852 | bt == VT_SHORT || | ||
| 5853 | bt == VT_DOUBLE || | ||
| 5854 | bt == VT_LDOUBLE || | ||
| 5833 | #if PTR_SIZE == 8 | 5855 | #if PTR_SIZE == 8 |
| 5834 | (bt == VT_LLONG && bit_size != 64) || | 5856 | (bt == VT_LLONG && bit_size != 64) || |
| 5835 | bt == VT_INT | 5857 | bt == VT_INT |
| 5836 | #else | 5858 | #else |
| 5837 | bt == VT_LLONG || | 5859 | bt == VT_LLONG || |
| 5838 | (bt == VT_INT && bit_size != 32) | 5860 | (bt == VT_INT && bit_size != 32) |
| 5839 | #endif | 5861 | #endif |
| 5840 | )) | 5862 | )) |
| 5841 | tcc_error("initializer element is not computable at load time"); | 5863 | tcc_error("initializer element is not computable at load time"); |
| 5842 | switch(bt) { | 5864 | switch(bt) { |
| 5843 | /* XXX: when cross-compiling we assume that each type has the | 5865 | /* XXX: when cross-compiling we assume that each type has the |
| 5844 | same representation on host and target, which is likely to | 5866 | same representation on host and target, which is likely to |
| 5845 | be wrong in the case of long double */ | 5867 | be wrong in the case of long double */ |
| 5846 | case VT_BOOL: | 5868 | case VT_BOOL: |
| 5847 | vtop->c.i = (vtop->c.i != 0); | 5869 | vtop->c.i = (vtop->c.i != 0); |
| 5848 | case VT_BYTE: | 5870 | case VT_BYTE: |
| 5849 | *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; | 5871 | *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; |
| 5850 | break; | 5872 | break; |
| 5851 | case VT_SHORT: | 5873 | case VT_SHORT: |
| 5852 | *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; | 5874 | *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; |
| 5853 | break; | 5875 | break; |
| 5854 | case VT_DOUBLE: | 5876 | case VT_DOUBLE: |
| 5855 | *(double *)ptr = vtop->c.d; | 5877 | *(double *)ptr = vtop->c.d; |
| 5856 | break; | 5878 | break; |
| 5857 | case VT_LDOUBLE: | 5879 | case VT_LDOUBLE: |
| 5858 | if (sizeof(long double) == LDOUBLE_SIZE) | 5880 | if (sizeof(long double) == LDOUBLE_SIZE) |
| 5859 | *(long double *)ptr = vtop->c.ld; | 5881 | *(long double *)ptr = vtop->c.ld; |
| 5860 | else if (sizeof(double) == LDOUBLE_SIZE) | 5882 | else if (sizeof(double) == LDOUBLE_SIZE) |
| 5861 | *(double *)ptr = vtop->c.ld; | 5883 | *(double *)ptr = vtop->c.ld; |
| 5862 | else | 5884 | else |
| 5863 | tcc_error("can't cross compile long double constants"); | 5885 | tcc_error("can't cross compile long double constants"); |
| 5864 | break; | 5886 | break; |
| 5865 | #if PTR_SIZE != 8 | 5887 | #if PTR_SIZE != 8 |
| 5866 | case VT_LLONG: | 5888 | case VT_LLONG: |
| 5867 | *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos; | 5889 | *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos; |
| 5868 | break; | 5890 | break; |
| 5869 | #else | 5891 | #else |
| 5870 | case VT_LLONG: | 5892 | case VT_LLONG: |
| 5871 | #endif | 5893 | #endif |
| 5872 | case VT_PTR: { | 5894 | case VT_PTR: |
| 5873 | addr_t val = (vtop->c.i & bit_mask) << bit_pos; | 5895 | { |
| 5896 | addr_t val = (vtop->c.i & bit_mask) << bit_pos; | ||
| 5874 | #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) | 5897 | #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) |
| 5875 | if (vtop->r & VT_SYM) | 5898 | if (vtop->r & VT_SYM) |
| 5876 | greloca(sec, vtop->sym, c, R_DATA_PTR, val); | 5899 | greloca(sec, vtop->sym, c, R_DATA_PTR, val); |
| 5877 | else | 5900 | else |
| 5878 | *(addr_t *)ptr |= val; | 5901 | *(addr_t *)ptr |= val; |
| 5879 | #else | 5902 | #else |
| 5880 | if (vtop->r & VT_SYM) | 5903 | if (vtop->r & VT_SYM) |
| 5881 | greloc(sec, vtop->sym, c, R_DATA_PTR); | 5904 | greloc(sec, vtop->sym, c, R_DATA_PTR); |
| 5882 | *(addr_t *)ptr |= val; | 5905 | *(addr_t *)ptr |= val; |
| 5883 | #endif | 5906 | #endif |
| 5884 | break; | 5907 | break; |
| 5885 | } | 5908 | } |
| 5886 | default: { | 5909 | default: |
| 5887 | int val = (vtop->c.i & bit_mask) << bit_pos; | 5910 | { |
| 5911 | int val = (vtop->c.i & bit_mask) << bit_pos; | ||
| 5888 | #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) | 5912 | #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) |
| 5889 | if (vtop->r & VT_SYM) | 5913 | if (vtop->r & VT_SYM) |
| 5890 | greloca(sec, vtop->sym, c, R_DATA_PTR, val); | 5914 | greloca(sec, vtop->sym, c, R_DATA_PTR, val); |
| 5891 | else | 5915 | else |
| 5892 | *(int *)ptr |= val; | 5916 | *(int *)ptr |= val; |
| 5893 | #else | 5917 | #else |
| 5894 | if (vtop->r & VT_SYM) | 5918 | if (vtop->r & VT_SYM) |
| 5895 | greloc(sec, vtop->sym, c, R_DATA_PTR); | 5919 | greloc(sec, vtop->sym, c, R_DATA_PTR); |
| 5896 | *(int *)ptr |= val; | 5920 | *(int *)ptr |= val; |
| 5897 | #endif | 5921 | #endif |
| 5898 | break; | 5922 | break; |
| 5899 | } | 5923 | } |
| 5900 | } | 5924 | } |
| 5925 | } | ||
| 5901 | vtop--; | 5926 | vtop--; |
| 5902 | } else { | 5927 | } else { |
| 5903 | vset(&dtype, VT_LOCAL|VT_LVAL, c); | 5928 | vset(&dtype, VT_LOCAL|VT_LVAL, c); |
| @@ -6006,6 +6031,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 102 unmodified lines | |||
| 6006 | ch = ((unsigned char *)tokc.str.data)[i]; | 6031 | ch = ((unsigned char *)tokc.str.data)[i]; |
| 6007 | else | 6032 | else |
| 6008 | ch = ((nwchar_t *)tokc.str.data)[i]; | 6033 | ch = ((nwchar_t *)tokc.str.data)[i]; |
| 6034 | vpushi(ch); | ||
| 6009 | init_putv(t1, sec, c + (array_length + i) * size1, | 6035 | init_putv(t1, sec, c + (array_length + i) * size1, |
| 6010 | ch, EXPR_VAL); | 6036 | ch, EXPR_VAL); |
| 6011 | } | 6037 | } |
| @@ -6018,6 +6044,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 6 unmodified lines | |||
| 6018 | warning in this case since it is standard) */ | 6044 | warning in this case since it is standard) */ |
| 6019 | if (n < 0 || array_length < n) { | 6045 | if (n < 0 || array_length < n) { |
| 6020 | if (!size_only) { | 6046 | if (!size_only) { |
| 6047 | vpushi(0); | ||
| 6021 | init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL); | 6048 | init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL); |
| 6022 | } | 6049 | } |
| 6023 | array_length++; | 6050 | array_length++; |
| @@ -6058,14 +6085,14 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 34 unmodified lines | |||
| 6058 | if (n < 0) | 6085 | if (n < 0) |
| 6059 | s->c = array_length; | 6086 | s->c = array_length; |
| 6060 | } else if ((type->t & VT_BTYPE) == VT_STRUCT && | 6087 | } else if ((type->t & VT_BTYPE) == VT_STRUCT && |
| 6061 | (sec || !first || tok == '{')) { | 6088 | (!first || tok == '{')) { |
| 6062 | 6089 | ||
| 6063 | /* NOTE: the previous test is a specific case for automatic | 6090 | /* NOTE: the previous test is a specific case for automatic |
| 6064 | struct/union init */ | 6091 | struct/union init */ |
| 6065 | /* XXX: union needs only one init */ | 6092 | /* XXX: union needs only one init */ |
| 6066 | 6093 | ||
| 6067 | int par_count = 0; | 6094 | int par_count = 0; |
| 6068 | if (tok == '(') { | 6095 | if (0 && tok == '(') { |
| 6069 | AttributeDef ad1; | 6096 | AttributeDef ad1; |
| 6070 | CType type1; | 6097 | CType type1; |
| 6071 | next(); | 6098 | next(); |
| @@ -6210,6 +6237,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 138 unmodified lines | |||
| 6210 | expr_type = EXPR_CONST; | 6237 | expr_type = EXPR_CONST; |
| 6211 | if (!sec) | 6238 | if (!sec) |
| 6212 | expr_type = EXPR_ANY; | 6239 | expr_type = EXPR_ANY; |
| 6240 | parse_init_elem(expr_type); | ||
| 6213 | init_putv(type, sec, c, 0, expr_type); | 6241 | init_putv(type, sec, c, 0, expr_type); |
| 6214 | } | 6242 | } |
| 6215 | } | 6243 | } |