From cf95ac399cbce1ea8a519f91dd36a5cfd4ea7943 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 25 Oct 2012 19:40:04 +0200 Subject: [PATCH] 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. --- tccgen.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tccgen.c b/tccgen.c index 2f6e4585..20cd4535 100644 --- a/tccgen.c +++ b/tccgen.c @@ -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) -- 2.11.4.GIT