aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2012-10-25 19:40:04 +0200
committerThomas Preud'homme <robotux@celest.fr>2012-10-25 19:40:50 +0200
commitcf95ac399cbce1ea8a519f91dd36a5cfd4ea7943 (patch)
tree693c29cb56c5351e7b740555920444750ae0fd4e
parent85f6fad3a6acbfa07a3dc45b673965fc26890d8e (diff)
downloadtinycc-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.
-rw-r--r--tccgen.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/tccgen.c b/tccgen.c
index 2f6e458..20cd453 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)