From a94e8d439acbaa1634e59420749ffdb7ee15e353 Mon Sep 17 00:00:00 2001 From: grischka Date: Fri, 6 May 2016 08:32:54 +0200 Subject: [PATCH] tccgen: scopes levels for local symbols (update 2) allow typedef int xxx; typedef int xxx; in the same scope as long as it is the same type --- tccgen.c | 25 ++++++++++++++----------- tests/Makefile | 1 + tests/pp/Makefile | 12 ++++++------ 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/tccgen.c b/tccgen.c index 6954d3a..7842309 100644 --- a/tccgen.c +++ b/tccgen.c @@ -2927,13 +2927,10 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) if (v < TOK_IDENT) expect("struct/union/enum name"); s = struct_find(v); - if (s && s->type.t == a) { - if (0 == local_scope) - goto do_decl; /* compatibility with past behavior */ - if (tok != '{' && tok != ';') - goto do_decl; /* variable declaration: 'struct s x;' */ - if (s->scope == local_scope && (s->c == -1 || tok != '{')) - goto do_decl; /* at least one must be incomplete type */ + if (s && (s->scope == local_scope || (tok != '{' && tok != ';'))) { + if (s->type.t != a) + tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); + goto do_decl; } } else { v = anon_sym++; @@ -3435,8 +3432,6 @@ static void post_type(CType *type, AttributeDef *ad) plast = &first; arg_size = 0; if (tok != ')') { - int ls = local_scope; - local_scope = 1; /* for struct decl inside function params */ for(;;) { /* read param name and compute offset */ if (l != FUNC_OLD) { @@ -3476,7 +3471,6 @@ static void post_type(CType *type, AttributeDef *ad) break; } } - local_scope = ls; } /* if no parameters, then old type prototype */ if (l == 0) @@ -6434,7 +6428,16 @@ static int decl0(int l, int is_for_loop_init) if (btype.t & VT_TYPEDEF) { /* save typedefed type */ /* XXX: test storage specifiers ? */ - sym = sym_push(v, &type, 0, 0); + sym = sym_find(v); + if (sym && sym->scope == local_scope) { + if (!is_compatible_types(&sym->type, &type) + || !(sym->type.t & VT_TYPEDEF)) + tcc_error("incompatible redefinition of '%s'", + get_tok_str(v, NULL)); + sym->type = type; + } else { + sym = sym_push(v, &type, 0, 0); + } sym->a = ad.a; sym->type.t |= VT_TYPEDEF; } else { diff --git a/tests/Makefile b/tests/Makefile index e9f173b..cf817ad 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -250,6 +250,7 @@ cache: tcc_g # clean clean: $(MAKE) -C tests2 $@ + $(MAKE) -C pp $@ rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc \ *-cc *-tcc *.exe \ hello libtcc_test vla_test tcctest[1234] ex? tcc_g diff --git a/tests/pp/Makefile b/tests/pp/Makefile index 7f42a3e..ad97f9b 100644 --- a/tests/pp/Makefile +++ b/tests/pp/Makefile @@ -8,16 +8,18 @@ TESTS += $(patsubst %.S,%.test,$(wildcard *.S)) all test : $(sort $(TESTS)) +DIFF_OPTS = -Nu -b -B -I "^\#" + %.test: %.c %.expect @echo PPTest $* ... -@$(TCC) -E -P $< >$*.output 2>&1 ; \ - diff -Nu -b -B -I "^#" $(EXTRA_DIFF_OPTS) $*.expect $*.output \ + diff $(DIFF_OPTS) $*.expect $*.output \ && rm -f $*.output %.test: %.S %.expect @echo PPTest $* ... -@$(TCC) -E -P $< >$*.output 2>&1 ; \ - diff -Nu -b -B -I "^#" $(EXTRA_DIFF_OPTS) $*.expect $*.output \ + diff $(DIFF_OPTS) $*.expect $*.output \ && rm -f $*.output # automatically generate .expect files with gcc: @@ -33,10 +35,8 @@ all test : $(sort $(TESTS)) clean: rm -vf *.output -# 02.test : EXTRA_DIFF_OPTS = -w -# 03.test : EXTRA_DIFF_OPTS = -w -# 04.test : EXTRA_DIFF_OPTS = -w -# 10.test : EXTRA_DIFF_OPTS = -w +02.test : DIFF_OPTS += -w +15.test : DIFF_OPTS += -w # diff options: # -b ighore space changes