| @@ -50,10 +50,10 @@ ST_DATA int nb_sym_pools; · 49 unmodified lines |
| 50 | 50 | |
| 51 | 51 | ST_DATA Sym *global_stack; |
| 52 | 52 | ST_DATA Sym *local_stack; |
| 53 | | −ST_DATA Sym *scope_stack_bottom; |
| 54 | 53 | ST_DATA Sym *define_stack; |
| 55 | 54 | ST_DATA Sym *global_label_stack; |
| 56 | 55 | ST_DATA Sym *local_label_stack; |
| 56 | +static int local_scope; |
| 57 | 57 | |
| 58 | 58 | ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ |
| 59 | 59 | 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 |
| 166 | 166 | ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c) |
| 167 | 167 | { |
| 168 | 168 | 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 | + |
| 177 | 170 | s = sym_malloc(); |
| 178 | 171 | s->asm_label = 0; |
| 179 | 172 | s->v = v; |
| @@ -246,6 +239,11 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) · 66 unmodified lines |
| 246 | 239 | ps = &ts->sym_identifier; |
| 247 | 240 | s->prev_tok = *ps; |
| 248 | 241 | *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 | + } |
| 249 | 247 | } |
| 250 | 248 | return s; |
| 251 | 249 | } |
| @@ -2930,10 +2928,11 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 2678 unmodified lines |
| 2930 | 2928 | if (v < TOK_IDENT) |
| 2931 | 2929 | expect("struct/union/enum name"); |
| 2932 | 2930 | 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 */ |
| 2937 | 2936 | } |
| 2938 | 2937 | } else { |
| 2939 | 2938 | v = anon_sym++; |
| @@ -3435,6 +3434,8 @@ static void post_type(CType *type, AttributeDef *ad) · 495 unmodified lines |
| 3435 | 3434 | plast = &first; |
| 3436 | 3435 | arg_size = 0; |
| 3437 | 3436 | if (tok != ')') { |
| 3437 | + int ls = local_scope; |
| 3438 | + local_scope = 1; /* for struct decl inside function params */ |
| 3438 | 3439 | for(;;) { |
| 3439 | 3440 | /* read param name and compute offset */ |
| 3440 | 3441 | if (l != FUNC_OLD) { |
| @@ -3474,6 +3475,7 @@ static void post_type(CType *type, AttributeDef *ad) · 33 unmodified lines |
| 3474 | 3475 | break; |
| 3475 | 3476 | } |
| 3476 | 3477 | } |
| 3478 | + local_scope = ls; |
| 3477 | 3479 | } |
| 3478 | 3480 | /* if no parameters, then old type prototype */ |
| 3479 | 3481 | if (l == 0) |
| @@ -4879,7 +4881,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 1399 unmodified lines |
| 4879 | 4881 | int case_reg, int is_expr) |
| 4880 | 4882 | { |
| 4881 | 4883 | int a, b, c, d; |
| 4882 | | − Sym *s, *frame_bottom; |
| 4884 | + Sym *s; |
| 4883 | 4885 | |
| 4884 | 4886 | /* generate line number info */ |
| 4885 | 4887 | 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 |
| 4933 | 4935 | next(); |
| 4934 | 4936 | /* record local declaration stack position */ |
| 4935 | 4937 | 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; |
| 4939 | 4938 | llabel = local_label_stack; |
| 4939 | + ++local_scope; |
| 4940 | 4940 | |
| 4941 | 4941 | /* handle local labels declarations */ |
| 4942 | 4942 | if (tok == TOK_LABEL) { |
| @@ -4983,7 +4983,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 40 unmodified lines |
| 4983 | 4983 | } |
| 4984 | 4984 | } |
| 4985 | 4985 | /* pop locally defined symbols */ |
| 4986 | | − scope_stack_bottom = scope_stack_bottom->next; |
| 4986 | + --local_scope; |
| 4987 | 4987 | sym_pop(&local_stack, s); |
| 4988 | 4988 | |
| 4989 | 4989 | /* 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 |
| 5082 | 5082 | next(); |
| 5083 | 5083 | skip('('); |
| 5084 | 5084 | 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; |
| 5088 | 5086 | if (tok != ';') { |
| 5089 | 5087 | /* c99 for-loop init decl? */ |
| 5090 | 5088 | 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 |
| 5119 | 5117 | gjmp_addr(c); |
| 5120 | 5118 | gsym(a); |
| 5121 | 5119 | gsym_addr(b, c); |
| 5122 | | − scope_stack_bottom = scope_stack_bottom->next; |
| 5120 | + --local_scope; |
| 5123 | 5121 | sym_pop(&local_stack, s); |
| 5122 | + |
| 5124 | 5123 | } else |
| 5125 | 5124 | if (tok == TOK_DO) { |
| 5126 | 5125 | next(); |
| @@ -6154,9 +6153,13 @@ static void gen_function(Sym *sym) · 1027 unmodified lines |
| 6154 | 6153 | /* put debug symbol */ |
| 6155 | 6154 | if (tcc_state->do_debug) |
| 6156 | 6155 | put_func_debug(sym); |
| 6156 | + |
| 6157 | 6157 | /* push a dummy symbol to enable local sym storage */ |
| 6158 | 6158 | sym_push2(&local_stack, SYM_FIELD, 0, 0); |
| 6159 | + local_scope = 1; /* for function parameters */ |
| 6159 | 6160 | gfunc_prolog(&sym->type); |
| 6161 | + local_scope = 0; |
| 6162 | + |
| 6160 | 6163 | #ifdef CONFIG_TCC_BCHECK |
| 6161 | 6164 | if (tcc_state->do_bounds_check && !strcmp(funcname, "main")) { |
| 6162 | 6165 | int i; |
| @@ -6177,7 +6180,7 @@ static void gen_function(Sym *sym) · 14 unmodified lines |
| 6177 | 6180 | cur_text_section->data_offset = ind; |
| 6178 | 6181 | label_pop(&global_label_stack, NULL); |
| 6179 | 6182 | /* reset local stack */ |
| 6180 | | − scope_stack_bottom = NULL; |
| 6183 | + local_scope = 0; |
| 6181 | 6184 | sym_pop(&local_stack, NULL); |
| 6182 | 6185 | /* end of function */ |
| 6183 | 6186 | /* patch symbol size */ |