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:
herman ten brugge 2022-03-21 11:40:43 +01:00
parent 8a3d0a0557
commit 313855c232
3 changed files with 74 additions and 2 deletions

1
tcc.h
View file

@ -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 */

View file

@ -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;

View file

@ -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)