aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Soroka <gits@joesoroka.com>2011-04-09 22:52:25 -0700
committerJoe Soroka <gits@joesoroka.com>2011-04-09 22:52:25 -0700
commit1446b543ae54643d904c15525fa75ab580b9ea23 (patch)
tree2b327adbcbc9e8acd2dfc9ed865fc2ef8cbbd840
parent7c7ca3c6aa095b195d277990b26bfd935315c28b (diff)
downloadtinycc-1446b543ae54643d904c15525fa75ab580b9ea23.tar.gz
tinycc-1446b543ae54643d904c15525fa75ab580b9ea23.tar.bz2
VLA fix [3/3]: store VLA sizeofs in anonymous runtime stack vars
-rw-r--r--tcc.h1
-rw-r--r--tccgen.c55
2 files changed, 22 insertions, 34 deletions
diff --git a/tcc.h b/tcc.h
index be53b65..fcbfadc 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 b55af88..bc9b24f 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);