mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-27 06:10:06 +08:00
VLA fix [3/3]: store VLA sizeofs in anonymous runtime stack vars
This commit is contained in:
parent
7c7ca3c6aa
commit
1446b543ae
1
tcc.h
1
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 {
|
||||
|
55
tccgen.c
55
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);
|
||||
|
Loading…
Reference in New Issue
Block a user