| @@ -358,17 +358,26 @@ static Sym *__sym_malloc(void) · 357 unmodified lines |
| 358 | 358 | static inline Sym *sym_malloc(void) |
| 359 | 359 | { |
| 360 | 360 | Sym *sym; |
| 361 | +#ifndef SYM_DEBUG |
| 361 | 362 | sym = sym_free_first; |
| 362 | 363 | if (!sym) |
| 363 | 364 | sym = __sym_malloc(); |
| 364 | 365 | sym_free_first = sym->next; |
| 365 | 366 | return sym; |
| 367 | +#else |
| 368 | + sym = tcc_malloc(sizeof(Sym)); |
| 369 | + return sym; |
| 370 | +#endif |
| 366 | 371 | } |
| 367 | 372 | |
| 368 | 373 | ST_INLN void sym_free(Sym *sym) |
| 369 | 374 | { |
| 375 | +#ifndef SYM_DEBUG |
| 370 | 376 | sym->next = sym_free_first; |
| 371 | 377 | sym_free_first = sym; |
| 378 | +#else |
| 379 | + tcc_free(sym); |
| 380 | +#endif |
| 372 | 381 | } |
| 373 | 382 | |
| 374 | 383 | /* push, without hashing */ |
| @@ -474,8 +483,9 @@ ST_FUNC Sym *global_identifier_push(int v, int t, int c) · 99 unmodified lines |
| 474 | 483 | return s; |
| 475 | 484 | } |
| 476 | 485 | |
| 477 | | −/* pop symbols until top reaches 'b' */ |
| 478 | | −ST_FUNC void sym_pop(Sym **ptop, Sym *b) |
| 486 | +/* pop symbols until top reaches 'b'. If KEEP is non-zero don't really |
| 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 | 490 | Sym *s, *ss, **ps; |
| 481 | 491 | TokenSym *ts; |
| @@ -495,10 +505,12 @@ ST_FUNC void sym_pop(Sym **ptop, Sym *b) · 13 unmodified lines |
| 495 | 505 | ps = &ts->sym_identifier; |
| 496 | 506 | *ps = s->prev_tok; |
| 497 | 507 | } |
| 498 | | − sym_free(s); |
| 508 | + if (!keep) |
| 509 | + sym_free(s); |
| 499 | 510 | s = ss; |
| 500 | 511 | } |
| 501 | | − *ptop = b; |
| 512 | + if (!keep) |
| 513 | + *ptop = b; |
| 502 | 514 | } |
| 503 | 515 | |
| 504 | 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 | 5419 | /* pop locally defined labels */ |
| 5408 | 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 | 5421 | /* pop locally defined symbols */ |
| 5428 | 5422 | --local_scope; |
| 5429 | | − sym_pop(&local_stack, s); |
| 5430 | | − |
| 5423 | + /* In the is_expr case (a statement expression is finished here), |
| 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 | 5432 | /* Pop VLA frames and restore stack pointer if required */ |
| 5432 | 5433 | if (vlas_in_scope > saved_vlas_in_scope) { |
| 5433 | 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 | 5568 | gsym(a); |
| 5568 | 5569 | gsym_addr(b, c); |
| 5569 | 5570 | --local_scope; |
| 5570 | | − sym_pop(&local_stack, s); |
| 5571 | + sym_pop(&local_stack, s, 0); |
| 5571 | 5572 | |
| 5572 | 5573 | } else |
| 5573 | 5574 | if (tok == TOK_DO) { |
| @@ -6592,7 +6593,7 @@ static void gen_function(Sym *sym) · 1018 unmodified lines |
| 6592 | 6593 | label_pop(&global_label_stack, NULL); |
| 6593 | 6594 | /* reset local stack */ |
| 6594 | 6595 | local_scope = 0; |
| 6595 | | − sym_pop(&local_stack, NULL); |
| 6596 | + sym_pop(&local_stack, NULL, 0); |
| 6596 | 6597 | /* end of function */ |
| 6597 | 6598 | /* patch symbol size */ |
| 6598 | 6599 | ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = |