aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrischka <grischka>2016-05-06 08:32:54 +0200
committergrischka <grischka>2016-05-06 08:32:54 +0200
commita94e8d439acbaa1634e59420749ffdb7ee15e353 (patch)
tree5a8fabc2a954dfba7a8e9da6dca2bad84e7d7b68
parentd48662d49650099e5ab9e1fe218311a18c2ff73a (diff)
downloadtinycc-a94e8d439acbaa1634e59420749ffdb7ee15e353.tar.gz
tinycc-a94e8d439acbaa1634e59420749ffdb7ee15e353.tar.bz2
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
-rw-r--r--tccgen.c25
-rw-r--r--tests/Makefile1
-rw-r--r--tests/pp/Makefile12
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