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 */
|
CType type; /* associated type */
|
||||||
union {
|
union {
|
||||||
|
int *vla_array_str; /* vla array code */
|
||||||
struct Sym *next; /* next related symbol (for fields and anoms) */
|
struct Sym *next; /* next related symbol (for fields and anoms) */
|
||||||
struct Sym *cleanupstate; /* in defined labels */
|
struct Sym *cleanupstate; /* in defined labels */
|
||||||
int asm_label; /* associated asm label */
|
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;
|
Sym **plast, *s, *first;
|
||||||
AttributeDef ad1;
|
AttributeDef ad1;
|
||||||
CType pt;
|
CType pt;
|
||||||
|
TokenString *vla_array_tok = NULL;
|
||||||
|
int *vla_array_str = NULL;
|
||||||
|
|
||||||
if (tok == '(') {
|
if (tok == '(') {
|
||||||
/* function type, or recursive declarator (return if so) */
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
if (tok != ']') {
|
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;
|
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();
|
gexpr();
|
||||||
|
end_macro();
|
||||||
|
next();
|
||||||
goto check;
|
goto check;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -5504,6 +5530,12 @@ check:
|
||||||
s = sym_push(SYM_FIELD, type, 0, n);
|
s = sym_push(SYM_FIELD, type, 0, n);
|
||||||
type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
|
type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
|
||||||
type->ref = s;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -8592,6 +8624,46 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
nocode_wanted = saved_nocode_wanted;
|
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
|
/* parse a function defined by symbol 'sym' and generate its code in
|
||||||
'cur_text_section' */
|
'cur_text_section' */
|
||||||
static void gen_function(Sym *sym)
|
static void gen_function(Sym *sym)
|
||||||
|
@ -8626,6 +8698,7 @@ static void gen_function(Sym *sym)
|
||||||
local_scope = 0;
|
local_scope = 0;
|
||||||
rsym = 0;
|
rsym = 0;
|
||||||
clear_temp_local_var_list();
|
clear_temp_local_var_list();
|
||||||
|
func_vla_arg(sym);
|
||||||
block(0);
|
block(0);
|
||||||
gsym(rsym);
|
gsym(rsym);
|
||||||
nocode_wanted = 0;
|
nocode_wanted = 0;
|
||||||
|
|
|
@ -3025,10 +3025,8 @@ void c99_vla_test_3(void)
|
||||||
a[1][2][3] = 2;
|
a[1][2][3] = 2;
|
||||||
c99_vla_test_3a(a);
|
c99_vla_test_3a(a);
|
||||||
c99_vla_test_3b(2, a);
|
c99_vla_test_3b(2, a);
|
||||||
#if 0 // FIXME
|
|
||||||
c99_vla_test_3c(3, a);
|
c99_vla_test_3c(3, a);
|
||||||
c99_vla_test_3d(4, a);
|
c99_vla_test_3d(4, a);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void c99_vla_test(void)
|
void c99_vla_test(void)
|
||||||
|
|
Loading…
Reference in a new issue