| @@ -358,17 +358,26 @@ static Sym *__sym_malloc(void) · 357 unmodified lines |
| 358 | static inline Sym *sym_malloc(void) | 358 | static inline Sym *sym_malloc(void) |
| 359 | { | 359 | { |
| 360 | Sym *sym; | 360 | Sym *sym; |
| | 361 | #ifndef SYM_DEBUG |
| 361 | sym = sym_free_first; | 362 | sym = sym_free_first; |
| 362 | if (!sym) | 363 | if (!sym) |
| 363 | sym = __sym_malloc(); | 364 | sym = __sym_malloc(); |
| 364 | sym_free_first = sym->next; | 365 | sym_free_first = sym->next; |
| 365 | return sym; | 366 | return sym; |
| | 367 | #else |
| | 368 | sym = tcc_malloc(sizeof(Sym)); |
| | 369 | return sym; |
| | 370 | #endif |
| 366 | } | 371 | } |
| 367 | | 372 | |
| 368 | ST_INLN void sym_free(Sym *sym) | 373 | ST_INLN void sym_free(Sym *sym) |
| 369 | { | 374 | { |
| | 375 | #ifndef SYM_DEBUG |
| 370 | sym->next = sym_free_first; | 376 | sym->next = sym_free_first; |
| 371 | sym_free_first = sym; | 377 | sym_free_first = sym; |
| | 378 | #else |
| | 379 | tcc_free(sym); |
| | 380 | #endif |
| 372 | } | 381 | } |
| 373 | | 382 | |
| 374 | /* push, without hashing */ | 383 | /* push, without hashing */ |
| @@ -474,8 +483,9 @@ ST_FUNC Sym *global_identifier_push(int v, int t, int c) · 99 unmodified lines |
| 474 | return s; | 483 | return s; |
| 475 | } | 484 | } |
| 476 | | 485 | |
| 477 | /* pop symbols until top reaches 'b' */ | 486 | /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really |
| 478 | ST_FUNC void sym_pop(Sym **ptop, Sym *b) | 487 | pop them yet from the list, but do remove them from the token array. */ |
| | 488 | ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep) |
| 479 | { | 489 | { |
| 480 | Sym *s, *ss, **ps; | 490 | Sym *s, *ss, **ps; |
| 481 | TokenSym *ts; | 491 | TokenSym *ts; |
| @@ -495,10 +505,12 @@ ST_FUNC void sym_pop(Sym **ptop, Sym *b) · 13 unmodified lines |
| 495 | ps = &ts->sym_identifier; | 505 | ps = &ts->sym_identifier; |
| 496 | *ps = s->prev_tok; | 506 | *ps = s->prev_tok; |
| 497 | } | 507 | } |
| 498 | sym_free(s); | 508 | if (!keep) |
| | 509 | sym_free(s); |
| 499 | s = ss; | 510 | s = ss; |
| 500 | } | 511 | } |
| 501 | *ptop = b; | 512 | if (!keep) |
| | 513 | *ptop = b; |
| 502 | } | 514 | } |
| 503 | | 515 | |
| 504 | static void weaken_symbol(Sym *sym) | 516 | static void weaken_symbol(Sym *sym) |
| @@ -5406,28 +5418,17 @@ static void block(int *bsym, int *csym, int is_expr) · 4901 unmodified lines |
| 5406 | } | 5418 | } |
| 5407 | /* pop locally defined labels */ | 5419 | /* pop locally defined labels */ |
| 5408 | label_pop(&local_label_stack, llabel); | 5420 | label_pop(&local_label_stack, llabel); |
| 5409 | if(is_expr) { | | |
| 5410 | /* XXX: this solution makes only valgrind happy... | | |
| 5411 | triggered by gcc.c-torture/execute/20000917-1.c */ | | |
| 5412 | Sym *p; | | |
| 5413 | switch(vtop->type.t & VT_BTYPE) { | | |
| 5414 | /* case VT_PTR: */ | | |
| 5415 | /* this breaks a compilation of the linux kernel v2.4.26 */ | | |
| 5416 | /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */ | | |
| 5417 | /* Look a commit a80acab: Display error on statement expressions with complex return type */ | | |
| 5418 | /* A pointer is not a complex return type */ | | |
| 5419 | case VT_STRUCT: | | |
| 5420 | case VT_ENUM: | | |
| 5421 | case VT_FUNC: | | |
| 5422 | for(p=vtop->type.ref;p;p=p->prev) | | |
| 5423 | if(p->prev==s) | | |
| 5424 | tcc_error("unsupported expression type"); | | |
| 5425 | } | | |
| 5426 | } | | |
| 5427 | /* pop locally defined symbols */ | 5421 | /* pop locally defined symbols */ |
| 5428 | --local_scope; | 5422 | --local_scope; |
| 5429 | sym_pop(&local_stack, s); | 5423 | /* In the is_expr case (a statement expression is finished here), |
| 5430 | | 5424 | vtop might refer to symbols on the local_stack. Either via the |
| | 5425 | type or via vtop->sym. We can't pop those nor any that in turn |
| | 5426 | might be referred to. To make it easier we don't roll back |
| | 5427 | any symbols in that case; some upper level call to block() will |
| | 5428 | do that. We do have to remove such symbols from the lookup |
| | 5429 | tables, though. sym_pop will do that. */ |
| | 5430 | sym_pop(&local_stack, s, is_expr); |
| | 5431 | |
| 5431 | /* Pop VLA frames and restore stack pointer if required */ | 5432 | /* Pop VLA frames and restore stack pointer if required */ |
| 5432 | if (vlas_in_scope > saved_vlas_in_scope) { | 5433 | if (vlas_in_scope > saved_vlas_in_scope) { |
| 5433 | vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc; | 5434 | vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc; |
| @@ -5567,7 +5568,7 @@ static void block(int *bsym, int *csym, int is_expr) · 133 unmodified lines |
| 5567 | gsym(a); | 5568 | gsym(a); |
| 5568 | gsym_addr(b, c); | 5569 | gsym_addr(b, c); |
| 5569 | --local_scope; | 5570 | --local_scope; |
| 5570 | sym_pop(&local_stack, s); | 5571 | sym_pop(&local_stack, s, 0); |
| 5571 | | 5572 | |
| 5572 | } else | 5573 | } else |
| 5573 | if (tok == TOK_DO) { | 5574 | if (tok == TOK_DO) { |
| @@ -6592,7 +6593,7 @@ static void gen_function(Sym *sym) · 1018 unmodified lines |
| 6592 | label_pop(&global_label_stack, NULL); | 6593 | label_pop(&global_label_stack, NULL); |
| 6593 | /* reset local stack */ | 6594 | /* reset local stack */ |
| 6594 | local_scope = 0; | 6595 | local_scope = 0; |
| 6595 | sym_pop(&local_stack, NULL); | 6596 | sym_pop(&local_stack, NULL, 0); |
| 6596 | /* end of function */ | 6597 | /* end of function */ |
| 6597 | /* patch symbol size */ | 6598 | /* patch symbol size */ |
| 6598 | ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = | 6599 | ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = |