Error out in case of variable name clash

Error out when two local variable with same name are defined in the same
scope. This fixes bug #15597 in savannah's BTS.
master
Thomas Preud'homme 2012-10-25 19:40:04 +02:00
parent 85f6fad3a6
commit cf95ac399c
1 changed files with 21 additions and 3 deletions

View File

@ -50,6 +50,7 @@ ST_DATA int nb_sym_pools;
ST_DATA Sym *global_stack;
ST_DATA Sym *local_stack;
ST_DATA Sym *scope_stack_bottom;
ST_DATA Sym *define_stack;
ST_DATA Sym *global_label_stack;
ST_DATA Sym *local_label_stack;
@ -147,6 +148,13 @@ ST_INLN void sym_free(Sym *sym)
ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
{
Sym *s;
if (ps == &local_stack) {
for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
tcc_error("incompatible types for redefinition of '%s'",
get_tok_str(v, NULL));
}
s = *ps;
s = sym_malloc();
s->asm_label = NULL;
s->v = v;
@ -4347,7 +4355,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
int case_reg, int is_expr)
{
int a, b, c, d;
Sym *s;
Sym *s, *frame_bottom;
/* generate line number info */
if (tcc_state->do_debug &&
@ -4398,6 +4406,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
next();
/* record local declaration stack position */
s = local_stack;
frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
frame_bottom->next = scope_stack_bottom;
scope_stack_bottom = frame_bottom;
llabel = local_label_stack;
/* handle local labels declarations */
if (tok == TOK_LABEL) {
@ -4440,6 +4451,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
}
}
/* pop locally defined symbols */
scope_stack_bottom = scope_stack_bottom->next;
sym_pop(&local_stack, s);
next();
} else if (tok == TOK_RETURN) {
@ -4510,6 +4522,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
next();
skip('(');
s = local_stack;
frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
frame_bottom->next = scope_stack_bottom;
scope_stack_bottom = frame_bottom;
if (tok != ';') {
/* c99 for-loop init decl? */
if (!decl0(VT_LOCAL, 1)) {
@ -4541,6 +4556,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
gjmp_addr(c);
gsym(a);
gsym_addr(b, c);
scope_stack_bottom = scope_stack_bottom->next;
sym_pop(&local_stack, s);
} else
if (tok == TOK_DO) {
@ -5509,7 +5525,9 @@ static void gen_function(Sym *sym)
gfunc_epilog();
cur_text_section->data_offset = ind;
label_pop(&global_label_stack, NULL);
sym_pop(&local_stack, NULL); /* reset local stack */
/* reset local stack */
scope_stack_bottom = NULL;
sym_pop(&local_stack, NULL);
/* end of function */
/* patch symbol size */
((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
@ -5577,7 +5595,7 @@ static int decl0(int l, int is_for_loop_init)
CType type, btype;
Sym *sym;
AttributeDef ad;
while (1) {
if (!parse_btype(&btype, &ad)) {
if (is_for_loop_init)