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