| @@ -39,15 +39,10 @@ ST_DATA Sym *define_stack; · 38 unmodified lines |
| 39 | ST_DATA Sym *global_label_stack; | 39 | ST_DATA Sym *global_label_stack; |
| 40 | ST_DATA Sym *local_label_stack; | 40 | ST_DATA Sym *local_label_stack; |
| 41 | | 41 | |
| 42 | static int local_scope; | 42 | static Sym *all_cleanups, *current_cleanups, *pending_gotos; |
| 43 | #define SCOPE_TCK_STORE_SIZE 512 | 43 | static int ncleanups; |
| 44 | ST_DATA ScopeTacker *scope_tracker; | | |
| 45 | static ScopeTacker scope_tck_store[SCOPE_TCK_STORE_SIZE]; | | |
| 46 | static int scope_tck_store_len; | | |
| 47 | | | |
| 48 | static ScopeTacker **scope_tck_2nd_store; | | |
| 49 | static int scope_tck_2nd_store_len; | | |
| 50 | | 44 | |
| | 45 | static int local_scope; |
| 51 | static int in_sizeof; | 46 | static int in_sizeof; |
| 52 | static int section_sym; | 47 | static int section_sym; |
| 53 | | 48 | |
| @@ -86,28 +81,7 @@ ST_DATA struct temp_local_variable { · 32 unmodified lines |
| 86 | short size; | 81 | short size; |
| 87 | short align; | 82 | short align; |
| 88 | } arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER]; | 83 | } arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER]; |
| 89 | | | |
| 90 | short nb_temp_local_vars; | 84 | short nb_temp_local_vars; |
| 91 | static struct cleanup { | | |
| 92 | ScopeTacker *scope; | | |
| 93 | struct { | | |
| 94 | Sym *var; | | |
| 95 | Sym *func; | | |
| 96 | } *syms; | | |
| 97 | int nb_cleanup; | | |
| 98 | } *cleanup_info; | | |
| 99 | | | |
| 100 | static struct cleanup **cleanup_info_store; | | |
| 101 | static int cleanup_idx; | | |
| 102 | | | |
| 103 | static struct CleanupGoto { | | |
| 104 | Sym *s; | | |
| 105 | ScopeTacker *scope; | | |
| 106 | int jnext; | | |
| 107 | int is_valide; | | |
| 108 | } **cleanup_goto_info; | | |
| 109 | | | |
| 110 | static int last_cleanup_goto; | | |
| 111 | | 85 | |
| 112 | /* ------------------------------------------------------------------------- */ | 86 | /* ------------------------------------------------------------------------- */ |
| 113 | | 87 | |
| @@ -141,59 +115,20 @@ static void clear_temp_local_var_list(); · 27 unmodified lines |
| 141 | | 115 | |
| 142 | static void incr_local_scope(void) | 116 | static void incr_local_scope(void) |
| 143 | { | 117 | { |
| 144 | ScopeTacker *tmp = scope_tracker; | | |
| 145 | | | |
| 146 | ++local_scope; | 118 | ++local_scope; |
| 147 | if (scope_tck_store_len >= SCOPE_TCK_STORE_SIZE) { | | |
| 148 | scope_tracker = tcc_malloc(sizeof(ScopeTacker)); | | |
| 149 | dynarray_add(&scope_tck_2nd_store, | | |
| 150 | &scope_tck_2nd_store_len, scope_tracker); | | |
| 151 | } else { | | |
| 152 | scope_tracker = &scope_tck_store[scope_tck_store_len]; | | |
| 153 | ++scope_tck_store_len; | | |
| 154 | } | | |
| 155 | scope_tracker->prev = tmp; | | |
| 156 | } | 119 | } |
| 157 | | 120 | |
| 158 | static void decr_local_scope(void) | 121 | static void decr_local_scope(void) |
| 159 | { | 122 | { |
| 160 | if (scope_tracker) | | |
| 161 | scope_tracker = scope_tracker->prev; | | |
| 162 | --local_scope; | 123 | --local_scope; |
| 163 | } | 124 | } |
| 164 | | 125 | |
| 165 | static void reset_local_scope(void) | 126 | static void reset_local_scope(void) |
| 166 | { | 127 | { |
| 167 | if (cleanup_info) { | 128 | if (current_cleanups) |
| 168 | int i = 0; | 129 | tcc_error("ICE current_cleanups"); |
| 169 | | 130 | sym_pop(&all_cleanups, NULL, 0); |
| 170 | for (; i < cleanup_idx; ++i) { | | |
| 171 | cleanup_info = cleanup_info_store[i]; | | |
| 172 | tcc_free(cleanup_info->syms); | | |
| 173 | tcc_free(cleanup_info); | | |
| 174 | } | | |
| 175 | cleanup_info = NULL; | | |
| 176 | cleanup_idx = 0; | | |
| 177 | tcc_free(cleanup_info_store); | | |
| 178 | cleanup_info_store = NULL; | | |
| 179 | dynarray_reset(&cleanup_goto_info, &last_cleanup_goto); | | |
| 180 | } | | |
| 181 | scope_tracker = NULL; | | |
| 182 | local_scope = 0; | 131 | local_scope = 0; |
| 183 | scope_tck_store_len = 0; | | |
| 184 | if (scope_tck_2nd_store_len) | | |
| 185 | dynarray_reset(&scope_tck_2nd_store, &scope_tck_2nd_store_len); | | |
| 186 | } | | |
| 187 | | | |
| 188 | int is_scope_a_parent_of(ScopeTacker *parent, ScopeTacker *child) | | |
| 189 | { | | |
| 190 | ScopeTacker *cur = parent->prev; | | |
| 191 | | | |
| 192 | for (; cur; cur = cur->prev) { | | |
| 193 | if (cur == child) | | |
| 194 | return 1; | | |
| 195 | } | | |
| 196 | return 0; | | |
| 197 | } | 132 | } |
| 198 | | 133 | |
| 199 | ST_INLN int is_float(int t) | 134 | ST_INLN int is_float(int t) |
| @@ -4646,8 +4581,6 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) · 4446 unmodified lines |
| 4646 | ret = pointed_type(type); | 4581 | ret = pointed_type(type); |
| 4647 | } | 4582 | } |
| 4648 | | 4583 | |
| 4649 | if (ad->cleanup_func) | | |
| 4650 | ad->should_remember = 1; | | |
| 4651 | if (tok == '(') { | 4584 | if (tok == '(') { |
| 4652 | /* This is possibly a parameter type list for abstract declarators | 4585 | /* This is possibly a parameter type list for abstract declarators |
| 4653 | ('int ()'), use post_type for testing this. */ | 4586 | ('int ()'), use post_type for testing this. */ |
| @@ -4799,67 +4732,43 @@ static void parse_builtin_params(int nc, const char *args) · 145 unmodified lines |
| 4799 | nocode_wanted--; | 4732 | nocode_wanted--; |
| 4800 | } | 4733 | } |
| 4801 | | 4734 | |
| 4802 | static void try_call_scope_cleanup(ScopeTacker *scope) | 4735 | static void try_call_scope_cleanup(Sym *stop) |
| 4803 | { | 4736 | { |
| 4804 | int i; | 4737 | Sym *cls = current_cleanups; |
| 4805 | | | |
| 4806 | if (!cleanup_info) | | |
| 4807 | return; | | |
| 4808 | | 4738 | |
| 4809 | if (cleanup_info->scope != scope) { | 4739 | for (; cls != stop; cls = cls->ncl) { |
| 4810 | int i = 0; | 4740 | Sym *fs = cls->next; |
| 4811 | | 4741 | Sym *vs = cls->prev_tok; |
| 4812 | for (; i < cleanup_idx; ++i) { | | |
| 4813 | cleanup_info = cleanup_info_store[i]; | | |
| 4814 | if (cleanup_info->scope == scope) | | |
| 4815 | goto found; | | |
| 4816 | } | | |
| 4817 | return; | | |
| 4818 | } | | |
| 4819 | found: | | |
| 4820 | for (i = cleanup_info->nb_cleanup - 1; i >= 0; --i) { | | |
| 4821 | Sym *fs = cleanup_info->syms[i].func; | | |
| 4822 | Sym *vs = cleanup_info->syms[i].var; | | |
| 4823 | | 4742 | |
| 4824 | vpushsym(&fs->type, fs); | 4743 | vpushsym(&fs->type, fs); |
| 4825 | if (is_float(vs->type.t)) { | | |
| 4826 | vs->type.t = VT_INT; | | |
| 4827 | } | | |
| 4828 | vset(&vs->type, vs->r, vs->c); | 4744 | vset(&vs->type, vs->r, vs->c); |
| 4829 | vtop->sym = vs; | 4745 | vtop->sym = vs; |
| | 4746 | mk_pointer(&vtop->type); |
| 4830 | gaddrof(); | 4747 | gaddrof(); |
| 4831 | gfunc_param_typed(fs, vs); | | |
| 4832 | gfunc_call(1); | 4748 | gfunc_call(1); |
| 4833 | } | 4749 | } |
| 4834 | } | 4750 | } |
| 4835 | | 4751 | |
| 4836 | static void try_call_cleanup_goto(ScopeTacker *dest_scope) | 4752 | static void try_call_cleanup_goto(Sym *cleanupstate) |
| 4837 | { | 4753 | { |
| 4838 | ScopeTacker *cur_scope_tracker; | 4754 | Sym *oc, *cc; |
| | 4755 | int ocd, ccd; |
| 4839 | | 4756 | |
| 4840 | if (!cleanup_info) | 4757 | if (!current_cleanups) |
| 4841 | return; | 4758 | return; |
| 4842 | for (cur_scope_tracker = scope_tracker; | | |
| 4843 | cur_scope_tracker && cur_scope_tracker != dest_scope; | | |
| 4844 | cur_scope_tracker = cur_scope_tracker->prev) { | | |
| 4845 | try_call_scope_cleanup(cur_scope_tracker); | | |
| 4846 | } | | |
| 4847 | } | | |
| 4848 | | 4759 | |
| 4849 | static void try_call_all_cleanup(void) | 4760 | /* search NCA of both cleanup chains given parents and initial depth */ |
| 4850 | { | 4761 | ocd = cleanupstate ? cleanupstate->v & ~SYM_FIELD : 0; |
| 4851 | ScopeTacker *cur_scope_tracker; | 4762 | for (ccd = ncleanups, oc = cleanupstate; ocd > ccd; --ocd, oc = oc->ncl) |
| | 4763 | ; |
| | 4764 | for (cc = current_cleanups; ccd > ocd; --ccd, cc = cc->ncl) |
| | 4765 | ; |
| | 4766 | for (; cc != oc; cc = cc->ncl, oc = oc->ncl, --ccd) |
| | 4767 | ; |
| 4852 | | 4768 | |
| 4853 | if (!cleanup_info) | 4769 | try_call_scope_cleanup(cc); |
| 4854 | return; | | |
| 4855 | for (cur_scope_tracker = scope_tracker; | | |
| 4856 | cur_scope_tracker; | | |
| 4857 | cur_scope_tracker = cur_scope_tracker->prev) { | | |
| 4858 | try_call_scope_cleanup(cur_scope_tracker); | | |
| 4859 | } | | |
| 4860 | } | 4770 | } |
| 4861 | | 4771 | |
| 4862 | | | |
| 4863 | ST_FUNC void unary(void) | 4772 | ST_FUNC void unary(void) |
| 4864 | { | 4773 | { |
| 4865 | int n, t, align, size, r, sizeof_caller; | 4774 | int n, t, align, size, r, sizeof_caller; |
| @@ -6252,14 +6161,16 @@ static void block(int *bsym, int *csym, int is_expr) · 1386 unmodified lines |
| 6252 | gsym(a); | 6161 | gsym(a); |
| 6253 | gsym_addr(b, d); | 6162 | gsym_addr(b, d); |
| 6254 | } else if (tok == '{') { | 6163 | } else if (tok == '{') { |
| 6255 | Sym *llabel; | 6164 | Sym *llabel, *lcleanup; |
| 6256 | int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope; | 6165 | int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope; |
| | 6166 | int lncleanups = ncleanups; |
| 6257 | | 6167 | |
| 6258 | next(); | 6168 | next(); |
| 6259 | /* record local declaration stack position */ | 6169 | /* record local declaration stack position */ |
| 6260 | s = local_stack; | 6170 | s = local_stack; |
| 6261 | llabel = local_label_stack; | 6171 | llabel = local_label_stack; |
| 6262 | incr_local_scope(); | 6172 | lcleanup = current_cleanups; |
| | 6173 | incr_local_scope(); |
| 6263 | | 6174 | |
| 6264 | /* handle local labels declarations */ | 6175 | /* handle local labels declarations */ |
| 6265 | while (tok == TOK_LABEL) { | 6176 | while (tok == TOK_LABEL) { |
| @@ -6289,32 +6200,35 @@ static void block(int *bsym, int *csym, int is_expr) · 23 unmodified lines |
| 6289 | } | 6200 | } |
| 6290 | } | 6201 | } |
| 6291 | | 6202 | |
| 6292 | if (cleanup_info) { | 6203 | if (current_cleanups != lcleanup) { |
| 6293 | int jmp = 0; | 6204 | int jmp = 0; |
| 6294 | int i; | 6205 | Sym *g, **pg; |
| 6295 | | 6206 | |
| 6296 | jmp = gjmp(jmp); | 6207 | for (pg = &pending_gotos; (g = *pg) && g->c > lncleanups;) |
| 6297 | | 6208 | if (g->prev_tok->r & LABEL_FORWARD) { |
| 6298 | for (i = 0; i < last_cleanup_goto; ++i) { | 6209 | Sym *pcl = g->next; |
| 6299 | struct CleanupGoto *cur = cleanup_goto_info[i]; | 6210 | if (!jmp) |
| 6300 | | 6211 | jmp = gjmp(0); |
| 6301 | if (!cur->is_valide) | 6212 | gsym(pcl->jnext); |
| 6302 | continue; | 6213 | try_call_scope_cleanup(lcleanup); |
| 6303 | if (scope_tracker == cur->scope || | 6214 | pcl->jnext = gjmp(0); |
| 6304 | is_scope_a_parent_of(cur->scope, scope_tracker)) { | 6215 | if (!lncleanups) |
| 6305 | gsym(cur->jnext); | 6216 | goto remove_pending; |
| 6306 | try_call_scope_cleanup(scope_tracker); | 6217 | g->c = lncleanups; |
| 6307 | cur->jnext = 0; | 6218 | pg = &g->prev; |
| 6308 | cur->jnext = gjmp(cur->jnext); | 6219 | } else { |
| 6309 | } | 6220 | remove_pending: |
| 6310 | } | 6221 | *pg = g->prev; |
| 6311 | | 6222 | sym_free(g); |
| 6312 | gsym(jmp); | 6223 | } |
| 6313 | if (!nocode_wanted) { | 6224 | gsym(jmp); |
| 6314 | try_call_scope_cleanup(scope_tracker); | 6225 | if (!nocode_wanted) { |
| 6315 | } | 6226 | try_call_scope_cleanup(lcleanup); |
| 6316 | } | 6227 | } |
| | 6228 | } |
| 6317 | | 6229 | |
| | 6230 | current_cleanups = lcleanup; |
| | 6231 | ncleanups = lncleanups; |
| 6318 | /* pop locally defined labels */ | 6232 | /* pop locally defined labels */ |
| 6319 | label_pop(&local_label_stack, llabel, is_expr); | 6233 | label_pop(&local_label_stack, llabel, is_expr); |
| 6320 | /* pop locally defined symbols */ | 6234 | /* pop locally defined symbols */ |
| @@ -6334,20 +6248,20 @@ static void block(int *bsym, int *csym, int is_expr) · 13 unmodified lines |
| 6334 | vla_sp_restore(); | 6248 | vla_sp_restore(); |
| 6335 | } | 6249 | } |
| 6336 | vlas_in_scope = saved_vlas_in_scope; | 6250 | vlas_in_scope = saved_vlas_in_scope; |
| 6337 | | 6251 | |
| 6338 | next(); | 6252 | next(); |
| 6339 | } else if (tok == TOK_RETURN) { | 6253 | } else if (tok == TOK_RETURN) { |
| 6340 | next(); | 6254 | next(); |
| 6341 | if (tok != ';') { | 6255 | if (tok != ';') { |
| 6342 | gexpr(); | 6256 | gexpr(); |
| 6343 | gen_assign_cast(&func_vt); | 6257 | gen_assign_cast(&func_vt); |
| 6344 | try_call_all_cleanup(); | 6258 | try_call_scope_cleanup(NULL); |
| 6345 | if ((func_vt.t & VT_BTYPE) == VT_VOID) | 6259 | if ((func_vt.t & VT_BTYPE) == VT_VOID) |
| 6346 | vtop--; | 6260 | vtop--; |
| 6347 | else | 6261 | else |
| 6348 | gfunc_return(&func_vt); | 6262 | gfunc_return(&func_vt); |
| 6349 | } else { | 6263 | } else { |
| 6350 | try_call_all_cleanup(); | 6264 | try_call_scope_cleanup(NULL); |
| 6351 | } | 6265 | } |
| 6352 | skip(';'); | 6266 | skip(';'); |
| 6353 | /* jump unless last stmt in top-level block */ | 6267 | /* jump unless last stmt in top-level block */ |
| @@ -6518,39 +6432,26 @@ static void block(int *bsym, int *csym, int is_expr) · 164 unmodified lines |
| 6518 | ggoto(); | 6432 | ggoto(); |
| 6519 | } else if (tok >= TOK_UIDENT) { | 6433 | } else if (tok >= TOK_UIDENT) { |
| 6520 | s = label_find(tok); | 6434 | s = label_find(tok); |
| 6521 | if (!s || s->jnext == -1) { | 6435 | /* put forward definition if needed */ |
| 6522 | /* put forward definition if needed */ | 6436 | if (!s) |
| 6523 | if (!s) | 6437 | s = label_push(&global_label_stack, tok, LABEL_FORWARD); |
| 6524 | s = label_push(&global_label_stack, tok, LABEL_FORWARD); | 6438 | else if (s->r == LABEL_DECLARED) |
| 6525 | if (cleanup_info) { | 6439 | s->r = LABEL_FORWARD; |
| 6526 | struct CleanupGoto *cur = | | |
| 6527 | tcc_malloc(sizeof(struct CleanupGoto)); | | |
| 6528 | | | |
| 6529 | cur->s = s; | | |
| 6530 | cur->is_valide = 1; | | |
| 6531 | s->jnext = -1; | | |
| 6532 | cur->jnext = 0; | | |
| 6533 | cur->scope = scope_tracker; | | |
| 6534 | cur->jnext = gjmp(cur->jnext); | | |
| 6535 | dynarray_add(&cleanup_goto_info, &last_cleanup_goto, cur); | | |
| 6536 | vla_sp_restore_root(); | | |
| 6537 | goto out_goto; | | |
| 6538 | } | | |
| 6539 | } else { | | |
| 6540 | if (cleanup_info && is_scope_a_parent_of(scope_tracker, | | |
| 6541 | s->scope)) | | |
| 6542 | try_call_cleanup_goto(s->scope); | | |
| 6543 | | | |
| 6544 | if (s->r == LABEL_DECLARED) | | |
| 6545 | s->r = LABEL_FORWARD; | | |
| 6546 | } | | |
| 6547 | | 6440 | |
| 6548 | vla_sp_restore_root(); | 6441 | vla_sp_restore_root(); |
| 6549 | if (s->r & LABEL_FORWARD) | 6442 | if (s->r & LABEL_FORWARD) { |
| | 6443 | /* start new goto chain for cleanups, linked via label->next */ |
| | 6444 | if (current_cleanups) { |
| | 6445 | sym_push2(&pending_gotos, SYM_FIELD, 0, ncleanups); |
| | 6446 | pending_gotos->prev_tok = s; |
| | 6447 | s = sym_push2(&s->next, SYM_FIELD, 0, 0); |
| | 6448 | pending_gotos->next = s; |
| | 6449 | } |
| 6550 | s->jnext = gjmp(s->jnext); | 6450 | s->jnext = gjmp(s->jnext); |
| 6551 | else | 6451 | } else { |
| | 6452 | try_call_cleanup_goto(s->cleanupstate); |
| 6552 | gjmp_addr(s->jnext); | 6453 | gjmp_addr(s->jnext); |
| 6553 | out_goto: | 6454 | } |
| 6554 | next(); | 6455 | next(); |
| 6555 | } else { | 6456 | } else { |
| 6556 | expect("label identifier"); | 6457 | expect("label identifier"); |
| @@ -6565,26 +6466,21 @@ static void block(int *bsym, int *csym, int is_expr) · 8 unmodified lines |
| 6565 | next(); | 6466 | next(); |
| 6566 | s = label_find(b); | 6467 | s = label_find(b); |
| 6567 | if (s) { | 6468 | if (s) { |
| 6568 | int is_gen = 0; | | |
| 6569 | int i; | | |
| 6570 | | | |
| 6571 | if (s->r == LABEL_DEFINED) | 6469 | if (s->r == LABEL_DEFINED) |
| 6572 | tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL)); | 6470 | tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL)); |
| 6573 | for (i = 0; i < last_cleanup_goto; ++i) { | | |
| 6574 | struct CleanupGoto *cur = cleanup_goto_info[i]; | | |
| 6575 | if (cur->s == s) { | | |
| 6576 | cur->is_valide = 0; | | |
| 6577 | gsym(cur->jnext); | | |
| 6578 | is_gen = 1; | | |
| 6579 | } | | |
| 6580 | } | | |
| 6581 | s->r = LABEL_DEFINED; | 6471 | s->r = LABEL_DEFINED; |
| 6582 | if (!is_gen) | 6472 | if (s->next) { |
| 6583 | gsym(s->jnext); | 6473 | Sym *pcl; /* pending cleanup goto */ |
| | 6474 | for (pcl = s->next; pcl; pcl = pcl->prev) |
| | 6475 | gsym(pcl->jnext); |
| | 6476 | sym_pop(&s->next, NULL, 0); |
| | 6477 | } else |
| | 6478 | gsym(s->jnext); |
| 6584 | } else { | 6479 | } else { |
| 6585 | s = label_push(&global_label_stack, b, LABEL_DEFINED); | 6480 | s = label_push(&global_label_stack, b, LABEL_DEFINED); |
| 6586 | } | 6481 | } |
| 6587 | s->jnext = ind; | 6482 | s->jnext = ind; |
| | 6483 | s->cleanupstate = current_cleanups; |
| 6588 | vla_sp_restore(); | 6484 | vla_sp_restore(); |
| 6589 | /* we accept this, but it is a mistake */ | 6485 | /* we accept this, but it is a mistake */ |
| 6590 | block_after_label: | 6486 | block_after_label: |
| @@ -7317,25 +7213,11 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 726 unmodified lines |
| 7317 | #endif | 7213 | #endif |
| 7318 | sym = sym_push(v, type, r, addr); | 7214 | sym = sym_push(v, type, r, addr); |
| 7319 | if (ad->cleanup_func) { | 7215 | if (ad->cleanup_func) { |
| 7320 | int nb_cleanup; | 7216 | Sym *cls = sym_push2(&all_cleanups, SYM_FIELD | ++ncleanups, 0, 0); |
| 7321 | | 7217 | cls->prev_tok = sym; |
| 7322 | if (!cleanup_info || cleanup_info->scope != scope_tracker) { | 7218 | cls->next = ad->cleanup_func; |
| 7323 | cleanup_info = tcc_malloc(sizeof(struct cleanup)); | 7219 | cls->ncl = current_cleanups; |
| 7324 | dynarray_add(&cleanup_info_store, &cleanup_idx, | 7220 | current_cleanups = cls; |
| 7325 | cleanup_info); | | |
| 7326 | cleanup_info ->scope = scope_tracker; | | |
| 7327 | cleanup_info->nb_cleanup = 0; | | |
| 7328 | cleanup_info->syms = NULL; | | |
| 7329 | } | | |
| 7330 | nb_cleanup = cleanup_info->nb_cleanup + 1; | | |
| 7331 | cleanup_info->syms = tcc_realloc(cleanup_info->syms, | | |
| 7332 | nb_cleanup * | | |
| 7333 | sizeof(*cleanup_info->syms)); | | |
| 7334 | cleanup_info->syms[nb_cleanup - 1].func = ad->cleanup_func; | | |
| 7335 | cleanup_info->syms[nb_cleanup - 1].var = sym; | | |
| 7336 | cleanup_info->nb_cleanup = nb_cleanup; | | |
| 7337 | if (!ad->should_remember) | | |
| 7338 | ad->cleanup_func = NULL; | | |
| 7339 | } | 7221 | } |
| 7340 | | 7222 | |
| 7341 | sym->a = ad->a; | 7223 | sym->a = ad->a; |
| @@ -7567,10 +7449,10 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 225 unmodified lines |
| 7567 | int v, has_init, r; | 7449 | int v, has_init, r; |
| 7568 | CType type, btype; | 7450 | CType type, btype; |
| 7569 | Sym *sym; | 7451 | Sym *sym; |
| 7570 | AttributeDef ad; | 7452 | AttributeDef ad, adbase; |
| 7571 | | 7453 | |
| 7572 | while (1) { | 7454 | while (1) { |
| 7573 | if (!parse_btype(&btype, &ad)) { | 7455 | if (!parse_btype(&btype, &adbase)) { |
| 7574 | if (is_for_loop_init) | 7456 | if (is_for_loop_init) |
| 7575 | return 0; | 7457 | return 0; |
| 7576 | /* skip redundant ';' if not in old parameter decl scope */ | 7458 | /* skip redundant ';' if not in old parameter decl scope */ |
| @@ -7618,6 +7500,7 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 41 unmodified lines |
| 7618 | if ((type.t & VT_ARRAY) && type.ref->c < 0) { | 7500 | if ((type.t & VT_ARRAY) && type.ref->c < 0) { |
| 7619 | type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c); | 7501 | type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c); |
| 7620 | } | 7502 | } |
| | 7503 | ad = adbase; |
| 7621 | type_decl(&type, &ad, &v, TYPE_DIRECT); | 7504 | type_decl(&type, &ad, &v, TYPE_DIRECT); |
| 7622 | #if 0 | 7505 | #if 0 |
| 7623 | { | 7506 | { |