History

tccgen: scope levels for local symbols

... for fast redeclaration checks Also, check function parameters too: void foo(int a) { int a; ... } Also, try to fix struct/union/enum's on different scopes: { struct xxx { int x; }; { struct xxx { int y; }; ... }} and some (probably not all) combination with incomplete declarations "struct xxx;" Replaces 2bfedb18675228c3837c23fa523231f55e102c12 and 07d896c8e5d1b46bf4aebd403c78e5f7ffebe02a Fixes cf95ac399cbce1ea8a519f91dd36a5cfd4ea7943

grischka committed 10 years ago

Commit caebbc31 parent 0fbc77c3 files · +30 −26Browse files

Unified · Split

3 files
  1. libtcc.c +0 −1
  2. tcc.h +4 −2
  3. tccgen.c +26 −23
libtcc.c+0−1
@@ -1764,7 +1764,6 @@ static const FlagDef flag_defs[] = { · 1763 unmodified lines
17641764 { offsetof(TCCState, old_struct_init_code), 0, "old-struct-init-code" },
17651765 { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },
17661766 { offsetof(TCCState, normalize_inc_dirs), 0, "normalize-inc-dirs" },
1767− { offsetof(TCCState, no_type_redef_check), FD_INVERT, "type-redefinition-check" },
17681767 };
17691768
17701769 /* set/reset a flag */
tcc.h+4−2
@@ -459,7 +459,10 @@ typedef struct AttributeDef { · 458 unmodified lines
459459 /* symbol management */
460460 typedef struct Sym {
461461 int v; /* symbol token */
462− int asm_label; /* associated asm label */
462+ union {
463+ int asm_label; /* associated asm label */
464+ int scope; /* scope level for locals */
465+ };
463466 union {
464467 long r; /* associated register */
465468 struct Attribute a;
@@ -707,7 +710,6 @@ struct TCCState { · 241 unmodified lines
707710 Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
708711 int dollars_in_identifiers; /* allows '$' char in indentifiers */
709712 int normalize_inc_dirs; /* remove non-existent or duplicate directories from include paths */
710− int no_type_redef_check; /* no local vars redefinition check */
711713
712714 /* warning switches */
713715 int warn_write_strings;
tccgen.c+26−23
@@ -50,10 +50,10 @@ ST_DATA int nb_sym_pools; · 49 unmodified lines
5050
5151 ST_DATA Sym *global_stack;
5252 ST_DATA Sym *local_stack;
53−ST_DATA Sym *scope_stack_bottom;
5453 ST_DATA Sym *define_stack;
5554 ST_DATA Sym *global_label_stack;
5655 ST_DATA Sym *local_label_stack;
56+static int local_scope;
5757
5858 ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
5959 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
@@ -166,14 +166,7 @@ ST_INLN void sym_free(Sym *sym) · 106 unmodified lines
166166 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
167167 {
168168 Sym *s;
169− if (!tcc_state->no_type_redef_check) {
170− if ((ps == &local_stack) && !(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
171− for (s = *ps; s != scope_stack_bottom; s = s->prev)
172− if (s->v == v)
173− tcc_error("incompatible types for redefinition of '%s'",
174− get_tok_str(v, NULL));
175− }
176− }
169+
177170 s = sym_malloc();
178171 s->asm_label = 0;
179172 s->v = v;
@@ -246,6 +239,11 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) · 66 unmodified lines
246239 ps = &ts->sym_identifier;
247240 s->prev_tok = *ps;
248241 *ps = s;
242+ if (local_scope) {
243+ s->scope = local_scope;
244+ if (s->prev_tok && s->prev_tok->scope == s->scope)
245+ tcc_error("redeclaration of '%s'", get_tok_str(v & ~SYM_STRUCT, NULL));
246+ }
249247 }
250248 return s;
251249 }
@@ -2930,10 +2928,11 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 2678 unmodified lines
29302928 if (v < TOK_IDENT)
29312929 expect("struct/union/enum name");
29322930 s = struct_find(v);
2933− if (s) {
2934− if (s->type.t != a)
2935− tcc_error("invalid type");
2936− goto do_decl;
2931+ if (s && s->type.t == a) {
2932+ if (tok != '{' && tok != ';')
2933+ goto do_decl; /* variable declaration: 'struct s x;' */
2934+ if (s->scope == local_scope && (s->c == -1 || tok != '{'))
2935+ goto do_decl; /* at least one must be incomplete type */
29372936 }
29382937 } else {
29392938 v = anon_sym++;
@@ -3435,6 +3434,8 @@ static void post_type(CType *type, AttributeDef *ad) · 495 unmodified lines
34353434 plast = &first;
34363435 arg_size = 0;
34373436 if (tok != ')') {
3437+ int ls = local_scope;
3438+ local_scope = 1; /* for struct decl inside function params */
34383439 for(;;) {
34393440 /* read param name and compute offset */
34403441 if (l != FUNC_OLD) {
@@ -3474,6 +3475,7 @@ static void post_type(CType *type, AttributeDef *ad) · 33 unmodified lines
34743475 break;
34753476 }
34763477 }
3478+ local_scope = ls;
34773479 }
34783480 /* if no parameters, then old type prototype */
34793481 if (l == 0)
@@ -4879,7 +4881,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 1399 unmodified lines
48794881 int case_reg, int is_expr)
48804882 {
48814883 int a, b, c, d;
4882− Sym *s, *frame_bottom;
4884+ Sym *s;
48834885
48844886 /* generate line number info */
48854887 if (tcc_state->do_debug &&
@@ -4933,10 +4935,8 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 47 unmodified lines
49334935 next();
49344936 /* record local declaration stack position */
49354937 s = local_stack;
4936− frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4937− frame_bottom->next = scope_stack_bottom;
4938− scope_stack_bottom = frame_bottom;
49394938 llabel = local_label_stack;
4939+ ++local_scope;
49404940
49414941 /* handle local labels declarations */
49424942 if (tok == TOK_LABEL) {
@@ -4983,7 +4983,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 40 unmodified lines
49834983 }
49844984 }
49854985 /* pop locally defined symbols */
4986− scope_stack_bottom = scope_stack_bottom->next;
4986+ --local_scope;
49874987 sym_pop(&local_stack, s);
49884988
49894989 /* Pop VLA frames and restore stack pointer if required */
@@ -5082,9 +5082,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 92 unmodified lines
50825082 next();
50835083 skip('(');
50845084 s = local_stack;
5085− frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
5086− frame_bottom->next = scope_stack_bottom;
5087− scope_stack_bottom = frame_bottom;
5085+ ++local_scope;
50885086 if (tok != ';') {
50895087 /* c99 for-loop init decl? */
50905088 if (!decl0(VT_LOCAL, 1)) {
@@ -5119,8 +5117,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 28 unmodified lines
51195117 gjmp_addr(c);
51205118 gsym(a);
51215119 gsym_addr(b, c);
5122− scope_stack_bottom = scope_stack_bottom->next;
5120+ --local_scope;
51235121 sym_pop(&local_stack, s);
5122+
51245123 } else
51255124 if (tok == TOK_DO) {
51265125 next();
@@ -6154,9 +6153,13 @@ static void gen_function(Sym *sym) · 1027 unmodified lines
61546153 /* put debug symbol */
61556154 if (tcc_state->do_debug)
61566155 put_func_debug(sym);
6156+
61576157 /* push a dummy symbol to enable local sym storage */
61586158 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6159+ local_scope = 1; /* for function parameters */
61596160 gfunc_prolog(&sym->type);
6161+ local_scope = 0;
6162+
61606163 #ifdef CONFIG_TCC_BCHECK
61616164 if (tcc_state->do_bounds_check && !strcmp(funcname, "main")) {
61626165 int i;
@@ -6177,7 +6180,7 @@ static void gen_function(Sym *sym) · 14 unmodified lines
61776180 cur_text_section->data_offset = ind;
61786181 label_pop(&global_label_stack, NULL);
61796182 /* reset local stack */
6180− scope_stack_bottom = NULL;
6183+ local_scope = 0;
61816184 sym_pop(&local_stack, NULL);
61826185 /* end of function */
61836186 /* patch symbol size */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t