Fix multi dimensional vla arrays on stack
There is no code generation in post_type for vla arrays. This code generation has to be delayed until gen_function. - post_type save code in type info. - gen_function use this code to generate vla code. - enable testcode for vla arrays.
This commit is contained in:
parent
8a3d0a0557
commit
313855c232
3 changed files with 74 additions and 2 deletions
1
tcc.h
1
tcc.h
|
@ -572,6 +572,7 @@ typedef struct Sym {
|
|||
};
|
||||
CType type; /* associated type */
|
||||
union {
|
||||
int *vla_array_str; /* vla array code */
|
||||
struct Sym *next; /* next related symbol (for fields and anoms) */
|
||||
struct Sym *cleanupstate; /* in defined labels */
|
||||
int asm_label; /* associated asm label */
|
||||
|
|
73
tccgen.c
73
tccgen.c
|
@ -5333,6 +5333,8 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
|
|||
Sym **plast, *s, *first;
|
||||
AttributeDef ad1;
|
||||
CType pt;
|
||||
TokenString *vla_array_tok = NULL;
|
||||
int *vla_array_str = NULL;
|
||||
|
||||
if (tok == '(') {
|
||||
/* function type, or recursive declarator (return if so) */
|
||||
|
@ -5441,8 +5443,32 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
|
|||
break;
|
||||
}
|
||||
if (tok != ']') {
|
||||
int nest = 1;
|
||||
|
||||
/* Code generation is not done now but has to be done
|
||||
at start of function. Save code here for later use. */
|
||||
nocode_wanted = 1;
|
||||
vla_array_tok = tok_str_alloc();
|
||||
for (;;) {
|
||||
if (tok == ']') {
|
||||
nest--;
|
||||
if (nest == 0)
|
||||
break;
|
||||
}
|
||||
if (tok == '[')
|
||||
nest++;
|
||||
tok_str_add_tok(vla_array_tok);
|
||||
next();
|
||||
}
|
||||
unget_tok(0);
|
||||
tok_str_add(vla_array_tok, -1);
|
||||
tok_str_add(vla_array_tok, 0);
|
||||
vla_array_str = vla_array_tok->str;
|
||||
begin_macro(vla_array_tok, 2);
|
||||
next();
|
||||
gexpr();
|
||||
end_macro();
|
||||
next();
|
||||
goto check;
|
||||
}
|
||||
break;
|
||||
|
@ -5504,6 +5530,12 @@ check:
|
|||
s = sym_push(SYM_FIELD, type, 0, n);
|
||||
type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
|
||||
type->ref = s;
|
||||
if (vla_array_str) {
|
||||
if (t1 & VT_VLA)
|
||||
s->vla_array_str = vla_array_str;
|
||||
else
|
||||
tok_str_free_str(vla_array_str);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -8592,6 +8624,46 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
|||
nocode_wanted = saved_nocode_wanted;
|
||||
}
|
||||
|
||||
/* generate vla code saved in post_type() */
|
||||
static void func_vla_arg_code(Sym *arg)
|
||||
{
|
||||
int align;
|
||||
TokenString *vla_array_tok = NULL;
|
||||
|
||||
if (arg->type.ref)
|
||||
func_vla_arg_code(arg->type.ref);
|
||||
|
||||
if (arg->type.t & VT_VLA) {
|
||||
loc -= type_size(&int_type, &align);
|
||||
loc &= -align;
|
||||
arg->type.ref->c = loc;
|
||||
|
||||
unget_tok(0);
|
||||
vla_array_tok = tok_str_alloc();
|
||||
vla_array_tok->str = arg->type.ref->vla_array_str;
|
||||
begin_macro(vla_array_tok, 1);
|
||||
next();
|
||||
gexpr();
|
||||
end_macro();
|
||||
next();
|
||||
vpush_type_size(&arg->type.ref->type, &align);
|
||||
gen_op('*');
|
||||
vset(&int_type, VT_LOCAL|VT_LVAL, arg->type.ref->c);
|
||||
vswap();
|
||||
vstore();
|
||||
vpop();
|
||||
}
|
||||
}
|
||||
|
||||
static void func_vla_arg(Sym *sym)
|
||||
{
|
||||
Sym *arg;
|
||||
|
||||
for (arg = sym->type.ref->next; arg; arg = arg->next)
|
||||
if (arg->type.t & VT_VLA)
|
||||
func_vla_arg_code(arg);
|
||||
}
|
||||
|
||||
/* parse a function defined by symbol 'sym' and generate its code in
|
||||
'cur_text_section' */
|
||||
static void gen_function(Sym *sym)
|
||||
|
@ -8626,6 +8698,7 @@ static void gen_function(Sym *sym)
|
|||
local_scope = 0;
|
||||
rsym = 0;
|
||||
clear_temp_local_var_list();
|
||||
func_vla_arg(sym);
|
||||
block(0);
|
||||
gsym(rsym);
|
||||
nocode_wanted = 0;
|
||||
|
|
|
@ -3025,10 +3025,8 @@ void c99_vla_test_3(void)
|
|||
a[1][2][3] = 2;
|
||||
c99_vla_test_3a(a);
|
||||
c99_vla_test_3b(2, a);
|
||||
#if 0 // FIXME
|
||||
c99_vla_test_3c(3, a);
|
||||
c99_vla_test_3d(4, a);
|
||||
#endif
|
||||
}
|
||||
|
||||
void c99_vla_test(void)
|
||||
|
|
Loading…
Reference in a new issue