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.
This commit is contained in:
Thomas Preud'homme 2012-10-25 19:40:04 +02:00
parent 85f6fad3a6
commit cf95ac399c

View File

@ -50,6 +50,7 @@ ST_DATA int nb_sym_pools;
ST_DATA Sym *global_stack; ST_DATA Sym *global_stack;
ST_DATA Sym *local_stack; ST_DATA Sym *local_stack;
ST_DATA Sym *scope_stack_bottom;
ST_DATA Sym *define_stack; ST_DATA Sym *define_stack;
ST_DATA Sym *global_label_stack; ST_DATA Sym *global_label_stack;
ST_DATA Sym *local_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) ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
{ {
Sym *s; 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 = sym_malloc();
s->asm_label = NULL; s->asm_label = NULL;
s->v = v; 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 case_reg, int is_expr)
{ {
int a, b, c, d; int a, b, c, d;
Sym *s; Sym *s, *frame_bottom;
/* generate line number info */ /* generate line number info */
if (tcc_state->do_debug && if (tcc_state->do_debug &&
@ -4398,6 +4406,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
next(); next();
/* record local declaration stack position */ /* record local declaration stack position */
s = local_stack; 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; llabel = local_label_stack;
/* handle local labels declarations */ /* handle local labels declarations */
if (tok == TOK_LABEL) { 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 */ /* pop locally defined symbols */
scope_stack_bottom = scope_stack_bottom->next;
sym_pop(&local_stack, s); sym_pop(&local_stack, s);
next(); next();
} else if (tok == TOK_RETURN) { } else if (tok == TOK_RETURN) {
@ -4510,6 +4522,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
next(); next();
skip('('); skip('(');
s = local_stack; 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 != ';') { if (tok != ';') {
/* c99 for-loop init decl? */ /* c99 for-loop init decl? */
if (!decl0(VT_LOCAL, 1)) { 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); gjmp_addr(c);
gsym(a); gsym(a);
gsym_addr(b, c); gsym_addr(b, c);
scope_stack_bottom = scope_stack_bottom->next;
sym_pop(&local_stack, s); sym_pop(&local_stack, s);
} else } else
if (tok == TOK_DO) { if (tok == TOK_DO) {
@ -5509,7 +5525,9 @@ static void gen_function(Sym *sym)
gfunc_epilog(); gfunc_epilog();
cur_text_section->data_offset = ind; cur_text_section->data_offset = ind;
label_pop(&global_label_stack, NULL); 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 */ /* end of function */
/* patch symbol size */ /* patch symbol size */
((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =