From 1446b543ae54643d904c15525fa75ab580b9ea23 Mon Sep 17 00:00:00 2001 From: Joe Soroka Date: Sat, 9 Apr 2011 22:52:25 -0700 Subject: [PATCH] VLA fix [3/3]: store VLA sizeofs in anonymous runtime stack vars --- tcc.h | 1 - tccgen.c | 55 ++++++++++++++++++++++--------------------------------- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/tcc.h b/tcc.h index be53b657..fcbfadcd 100644 --- a/tcc.h +++ b/tcc.h @@ -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 { diff --git a/tccgen.c b/tccgen.c index b55af88d..bc9b24fb 100644 --- a/tccgen.c +++ b/tccgen.c @@ -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); -- 2.11.4.GIT