From db560e9439deaef3c15aa353828fd4d98a1b5f8c Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sat, 5 Feb 2011 02:31:45 +0100 Subject: Revert "Implement C99 Variable Length Arrays" This reverts commit a5a50eaafeea0d3ca47bc8fb6baf983743470c60. --- tccgen.c | 160 ++++++++++++--------------------------------------------------- 1 file changed, 30 insertions(+), 130 deletions(-) (limited to 'tccgen.c') diff --git a/tccgen.c b/tccgen.c index 7fb7cfe..7144ccd 100644 --- a/tccgen.c +++ b/tccgen.c @@ -78,7 +78,6 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_re static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); static void expr_eq(void); static void unary_type(CType *type); -static void vla_runtime_type_size(CType *type, int *a); static int is_compatible_parameter_types(CType *type1, CType *type2); static void expr_type(CType *type); @@ -1456,12 +1455,6 @@ static int pointed_size(CType *type) return type_size(pointed_type(type), &align); } -static void vla_runtime_pointed_size(CType *type) -{ - int align; - vla_runtime_type_size(pointed_type(type), &align); -} - static inline int is_null_pointer(SValue *p) { if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) @@ -1550,20 +1543,11 @@ ST_FUNC void gen_op(int op) } /* if both pointers, then it must be the '-' op */ if (bt1 == VT_PTR && bt2 == VT_PTR) { - int ptr1_is_vla; - - ptr1_is_vla = 0; if (op != '-') error("cannot use pointers here"); check_comparison_pointer_types(vtop - 1, vtop, op); /* XXX: check that types are compatible */ - if (vtop[-1].type.t & VT_VLA) { - vla_runtime_pointed_size(&vtop[-1].type); - vrott(3); - ptr1_is_vla = 1; - } else { - u = pointed_size(&vtop[-1].type); - } + u = pointed_size(&vtop[-1].type); gen_opic(op); /* set to integer type */ #ifdef TCC_TARGET_X86_64 @@ -1571,10 +1555,7 @@ ST_FUNC void gen_op(int op) #else vtop->type.t = VT_INT; #endif - if (ptr1_is_vla) - vswap(); - else - vpushi(u); + vpushi(u); gen_op(TOK_PDIV); } else { /* exactly one pointer : must be '+' or '-'. */ @@ -1586,20 +1567,16 @@ ST_FUNC void gen_op(int op) swap(&t1, &t2); } type1 = vtop[-1].type; - type1.t &= ~(VT_ARRAY|VT_VLA); - if (vtop[-1].type.t & VT_VLA) - vla_runtime_pointed_size(&vtop[-1].type); - else { - u = pointed_size(&vtop[-1].type); - if (u < 0) - error("unknown array element size"); + type1.t &= ~VT_ARRAY; + u = pointed_size(&vtop[-1].type); + if (u < 0) + error("unknown array element size"); #ifdef TCC_TARGET_X86_64 - vpushll(u); + vpushll(u); #else - /* XXX: cast to int ? (long long case) */ - vpushi(u); + /* XXX: cast to int ? (long long case) */ + vpushi(u); #endif - } gen_op('*'); #ifdef CONFIG_TCC_BCHECK /* if evaluating constant expression, no code should be @@ -1955,7 +1932,7 @@ static void gen_cast(CType *type) vtop->type = *type; } -/* return type size as known at compile time. Put alignment at 'a' */ +/* return type size. Put alignment at 'a' */ ST_FUNC int type_size(CType *type, int *a) { Sym *s; @@ -1968,10 +1945,7 @@ ST_FUNC int type_size(CType *type, int *a) *a = s->r; return s->c; } else if (bt == VT_PTR) { - if (type->t & VT_VLA) { - *a = 1; - return 0; - } else if (type->t & VT_ARRAY) { + if (type->t & VT_ARRAY) { int ts; s = type->ref; @@ -2018,30 +1992,6 @@ ST_FUNC int type_size(CType *type, int *a) } } -/* push type size as known at runtime time on top of value stack. Put - alignment at 'a' */ -ST_FUNC void vla_runtime_type_size(CType *type, int *a) -{ - if (type->t & VT_VLA) { - Sym *s; - - s = type->ref; - vla_runtime_type_size(&s->type, a); - vpushv(s->s); - if ((vtop->r & (VT_SYM|VT_LVAL|VT_VALMASK)) != VT_CONST) { - gv_dup(); - vswap(); - vpop(); - } - gen_op('*'); - } else { - int size; - - size = type_size(type, a); - vpushi(size); - } -} - /* return the pointed type of t */ static inline CType *pointed_type(CType *type) { @@ -3153,43 +3103,25 @@ static void post_type(CType *type, AttributeDef *ad) type->t = t1 | VT_FUNC; type->ref = s; } else if (tok == '[') { - SValue *last_vtop = NULL; - /* array definition */ next(); if (tok == TOK_RESTRICT1) next(); n = -1; if (tok != ']') { - gexpr(); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - n = vtop->c.i; - last_vtop = vtop; - if (n < 0) - error("invalid array size"); - } else { - if (!is_integer_btype(vtop->type.t & VT_BTYPE)) - error("size of variable length array should be an integer"); - type->t |= VT_VLA; - last_vtop = vtop; - } + n = expr_const(); + if (n < 0) + error("invalid array size"); } skip(']'); /* parse next post type */ - t1 = type->t & (VT_STORAGE|VT_VLA); - type->t &= ~(VT_STORAGE|VT_VLA); + t1 = type->t & VT_STORAGE; + type->t &= ~VT_STORAGE; post_type(type, ad); - t1 |= type->t & VT_VLA; - /* we push an anonymous symbol which will contain the array + /* we push a anonymous symbol which will contain the array element type */ s = sym_push(SYM_FIELD, type, 0, n); - if (t1 & VT_VLA) { - s->s = last_vtop; // That's ok, we don't need n with VLA - } else { - if (n >= 0) - vpop(); - } type->t = t1 | VT_ARRAY | VT_PTR; type->ref = s; } @@ -3558,18 +3490,11 @@ ST_FUNC void unary(void) next(); in_sizeof++; unary_type(&type); // Perform a in_sizeof = 0; - if ((t == TOK_SIZEOF) && (type.t & VT_VLA)) { - vla_runtime_type_size(&type, &align); - size = 0; - } else { - size = type_size(&type, &align); - } + size = type_size(&type, &align); if (t == TOK_SIZEOF) { - if (!(type.t & VT_VLA)) { - if (size < 0) - error("sizeof applied to an incomplete type"); - vpushi(size); - } + if (size < 0) + error("sizeof applied to an incomplete type"); + vpushi(size); } else { vpushi(align); } @@ -3728,10 +3653,7 @@ ST_FUNC void unary(void) } else { r = s->r; } - if (s->type.t & VT_VLA) - vpushv(s->s); - else - vset(&s->type, r, s->c); + vset(&s->type, r, s->c); /* if forward reference, we must point to s */ if (vtop->r & VT_SYM) { vtop->sym = s; @@ -4860,18 +4782,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, Sym *s, *f; CType *t1; - if (type->t & VT_VLA) { - int a; - CValue retcval; - - vpush_global_sym(&func_old_type, TOK_alloca); - vla_runtime_type_size(type, &a); - gfunc_call(1); - - /* return value */ - retcval.i = 0; - vsetc(type, REG_IRET, &retcval); - } else if (type->t & VT_ARRAY) { + if (type->t & VT_ARRAY) { s = type->ref; n = s->c; array_length = 0; @@ -5102,7 +5013,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, ParseState saved_parse_state = {0}; TokenString init_str; Section *sec; - Sym *vla = NULL; size = type_size(type, &align); /* If unknown size, we must evaluate it before @@ -5168,12 +5078,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, if ((r & VT_VALMASK) == VT_LOCAL) { sec = NULL; #ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) { - if (type->t & VT_VLA) - warning("Array bound check don't work for VLA"); - else - loc--; - } + if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) + loc--; #endif loc = (loc - size) & -align; addr = loc; @@ -5181,8 +5087,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, /* handles bounds */ /* XXX: currently, since we do only one pass, we cannot track '&' operators, so we add only arrays */ - if (tcc_state->do_bounds_check && (type->t & VT_ARRAY) && - !(type->t & VT_VLA)) { + if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) { unsigned long *bounds_ptr; /* add padding between regions */ loc--; @@ -5194,7 +5099,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, #endif if (v) { /* local variable */ - vla = sym_push(v, type, r, addr); + sym_push(v, type, r, addr); } else { /* push local reference */ vset(type, r, addr); @@ -5309,10 +5214,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, } #endif } - if (has_init || (type->t & VT_VLA)) { + if (has_init) { decl_initializer(type, sec, addr, 1, 0); - if (type->t & VT_VLA) - vla->s = vtop; /* restore parse state if needed */ if (init_str.str) { tok_str_free(init_str.str); @@ -5681,12 +5584,9 @@ ST_FUNC void decl(int l) if (!(type.t & VT_ARRAY)) r |= lvalue_type(type.t); has_init = (tok == '='); - if (has_init && (type.t & VT_VLA)) - error("Variable length array cannot be initialized"); if ((btype.t & VT_EXTERN) || - ((type.t & VT_ARRAY) && (!(type.t & VT_VLA)) && - (type.t & VT_STATIC) && !has_init && l == VT_CONST && - type.ref->c < 0)) { + ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && + !has_init && l == VT_CONST && type.ref->c < 0)) { /* external variable */ /* NOTE: as GCC, uninitialized global static arrays of null size are considered as -- cgit v1.3.1