diff options
| author | Thomas Preud'homme <robotux@celest.fr> | 2012-10-25 19:40:04 +0200 |
|---|---|---|
| committer | Thomas Preud'homme <robotux@celest.fr> | 2012-10-25 19:40:50 +0200 |
| commit | cf95ac399cbce1ea8a519f91dd36a5cfd4ea7943 (patch) | |
| tree | 693c29cb56c5351e7b740555920444750ae0fd4e /tccgen.c | |
| parent | 85f6fad3a6acbfa07a3dc45b673965fc26890d8e (diff) | |
| download | tinycc-cf95ac399cbce1ea8a519f91dd36a5cfd4ea7943.tar.gz tinycc-cf95ac399cbce1ea8a519f91dd36a5cfd4ea7943.tar.bz2 | |
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.
Diffstat (limited to 'tccgen.c')
| -rw-r--r-- | tccgen.c | 24 |
1 files changed, 21 insertions, 3 deletions
@@ -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) |
