diff options
| author | Joe Soroka <gits@joesoroka.com> | 2011-04-09 22:52:25 -0700 |
|---|---|---|
| committer | Joe Soroka <gits@joesoroka.com> | 2011-04-09 22:52:25 -0700 |
| commit | 1446b543ae54643d904c15525fa75ab580b9ea23 (patch) | |
| tree | 2b327adbcbc9e8acd2dfc9ed865fc2ef8cbbd840 | |
| parent | 7c7ca3c6aa095b195d277990b26bfd935315c28b (diff) | |
| download | tinycc-1446b543ae54643d904c15525fa75ab580b9ea23.tar.gz tinycc-1446b543ae54643d904c15525fa75ab580b9ea23.tar.bz2 | |
VLA fix [3/3]: store VLA sizeofs in anonymous runtime stack vars
| -rw-r--r-- | tcc.h | 1 | ||||
| -rw-r--r-- | tccgen.c | 55 |
2 files changed, 22 insertions, 34 deletions
@@ -224,7 +224,6 @@ typedef struct Sym { union { long c; /* associated number */ int *d; /* define token stream */ - SValue *s; /* associated stack value */ }; CType type; /* associated type */ union { @@ -2036,22 +2036,9 @@ ST_FUNC int type_size(CType *type, int *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('*'); + vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c); } else { - int size; - - size = type_size(type, a); - vpushi(size); + vpushi(type_size(type, a)); } } @@ -3170,8 +3157,6 @@ static void post_type(CType *type, AttributeDef *ad) type->t = VT_FUNC; type->ref = s; } else if (tok == '[') { - SValue *last_vtop = NULL; - /* array definition */ next(); if (tok == TOK_RESTRICT1) @@ -3182,14 +3167,12 @@ static void post_type(CType *type, AttributeDef *ad) 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"); t1 = VT_VLA; - last_vtop = vtop; } } skip(']'); @@ -3197,15 +3180,23 @@ static void post_type(CType *type, AttributeDef *ad) post_type(type, ad); t1 |= type->t & VT_VLA; + if (t1 & VT_VLA) { + loc -= type_size(&int_type, &align); + loc &= -align; + n = loc; + + vla_runtime_type_size(type, &align); + gen_op('*'); + vset(&int_type, VT_LOCAL|VT_LVAL, loc); + vswap(); + vstore(); + } + if (n != -1) + vpop(); + /* we push an 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_VLA : VT_ARRAY) | VT_PTR; type->ref = s; } @@ -3741,10 +3732,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; @@ -4895,6 +4883,10 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, /* return value */ retcval.i = 0; vsetc(type, REG_IRET, &retcval); + vset(type, VT_LOCAL|VT_LVAL, c); + vswap(); + vstore(); + vpop(); } else if (type->t & VT_ARRAY) { s = type->ref; n = s->c; @@ -5132,7 +5124,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; Sym *flexible_array; flexible_array = NULL; @@ -5233,7 +5224,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); @@ -5348,8 +5339,6 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, } if (has_init || (type->t & VT_VLA)) { 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); |
