| @@ -44,6 +44,7 @@ static int ncleanups; · 43 unmodified lines |
| 44 | | 44 | |
| 45 | static int local_scope; | 45 | static int local_scope; |
| 46 | static int in_sizeof; | 46 | static int in_sizeof; |
| | 47 | static int in_generic; |
| 47 | static int section_sym; | 48 | static int section_sym; |
| 48 | | 49 | |
| 49 | ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ | 50 | ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ |
| @@ -56,6 +57,24 @@ ST_DATA int const_wanted; /* true if constant wanted */ · 6 unmodified lines |
| 56 | ST_DATA int nocode_wanted; /* no code generation wanted */ | 57 | ST_DATA int nocode_wanted; /* no code generation wanted */ |
| 57 | #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */ | 58 | #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */ |
| 58 | #define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */ | 59 | #define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */ |
| | 60 | |
| | 61 | /* Automagical code suppression ----> */ |
| | 62 | #define CODE_OFF() (nocode_wanted |= 0x20000000) |
| | 63 | #define CODE_ON() (nocode_wanted &= ~0x20000000) |
| | 64 | |
| | 65 | /* Clear 'nocode_wanted' at label if it was used */ |
| | 66 | ST_FUNC void gsym(int t) { if (t) { gsym_addr(t, ind); CODE_ON(); }} |
| | 67 | static int gind(void) { CODE_ON(); return ind; } |
| | 68 | |
| | 69 | /* Set 'nocode_wanted' after unconditional jumps */ |
| | 70 | static void gjmp_addr_acs(int t) { gjmp_addr(t); CODE_OFF(); } |
| | 71 | static int gjmp_acs(int t) { t = gjmp(t); CODE_OFF(); return t; } |
| | 72 | |
| | 73 | /* These are #undef'd at the end of this file */ |
| | 74 | #define gjmp_addr gjmp_addr_acs |
| | 75 | #define gjmp gjmp_acs |
| | 76 | /* <---- */ |
| | 77 | |
| 59 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ | 78 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ |
| 60 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ | 79 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ |
| 61 | ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */ | 80 | ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */ |
| @@ -3544,8 +3563,7 @@ redo: · 3482 unmodified lines |
| 3544 | break; | 3563 | break; |
| 3545 | case TOK_NORETURN1: | 3564 | case TOK_NORETURN1: |
| 3546 | case TOK_NORETURN2: | 3565 | case TOK_NORETURN2: |
| 3547 | /* currently, no need to handle it because tcc does not | 3566 | ad->f.func_noreturn = 1; |
| 3548 | track unused objects */ | | |
| 3549 | break; | 3567 | break; |
| 3550 | case TOK_CDECL1: | 3568 | case TOK_CDECL1: |
| 3551 | case TOK_CDECL2: | 3569 | case TOK_CDECL2: |
| @@ -4129,7 +4147,7 @@ static void parse_btype_qualify(CType *type, int qualifiers) · 577 unmodified lines |
| 4129 | */ | 4147 | */ |
| 4130 | static int parse_btype(CType *type, AttributeDef *ad) | 4148 | static int parse_btype(CType *type, AttributeDef *ad) |
| 4131 | { | 4149 | { |
| 4132 | int t, u, bt, st, type_found, typespec_found, g; | 4150 | int t, u, bt, st, type_found, typespec_found, g, n; |
| 4133 | Sym *s; | 4151 | Sym *s; |
| 4134 | CType type1; | 4152 | CType type1; |
| 4135 | | 4153 | |
| @@ -4336,6 +4354,14 @@ static int parse_btype(CType *type, AttributeDef *ad) · 200 unmodified lines |
| 4336 | s = sym_find(tok); | 4354 | s = sym_find(tok); |
| 4337 | if (!s || !(s->type.t & VT_TYPEDEF)) | 4355 | if (!s || !(s->type.t & VT_TYPEDEF)) |
| 4338 | goto the_end; | 4356 | goto the_end; |
| | 4357 | |
| | 4358 | n = tok, next(); |
| | 4359 | if (tok == ':' && !in_generic) { |
| | 4360 | /* ignore if it's a label */ |
| | 4361 | unget_tok(n); |
| | 4362 | goto the_end; |
| | 4363 | } |
| | 4364 | |
| 4339 | t &= ~(VT_BTYPE|VT_LONG); | 4365 | t &= ~(VT_BTYPE|VT_LONG); |
| 4340 | u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u; | 4366 | u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u; |
| 4341 | type->t = (s->type.t & ~VT_TYPEDEF) | u; | 4367 | type->t = (s->type.t & ~VT_TYPEDEF) | u; |
| @@ -4345,7 +4371,6 @@ static int parse_btype(CType *type, AttributeDef *ad) · 3 unmodified lines |
| 4345 | t = type->t; | 4371 | t = type->t; |
| 4346 | /* get attributes from typedef */ | 4372 | /* get attributes from typedef */ |
| 4347 | sym_to_attr(ad, s); | 4373 | sym_to_attr(ad, s); |
| 4348 | next(); | | |
| 4349 | typespec_found = 1; | 4374 | typespec_found = 1; |
| 4350 | st = bt = -2; | 4375 | st = bt = -2; |
| 4351 | break; | 4376 | break; |
| @@ -5237,7 +5262,11 @@ ST_FUNC void unary(void) · 885 unmodified lines |
| 5237 | AttributeDef ad_tmp; | 5262 | AttributeDef ad_tmp; |
| 5238 | int itmp; | 5263 | int itmp; |
| 5239 | CType cur_type; | 5264 | CType cur_type; |
| | 5265 | |
| | 5266 | in_generic++; |
| 5240 | parse_btype(&cur_type, &ad_tmp); | 5267 | parse_btype(&cur_type, &ad_tmp); |
| | 5268 | in_generic--; |
| | 5269 | |
| 5241 | type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); | 5270 | type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); |
| 5242 | if (compare_types(&controlling_type, &cur_type, 0)) { | 5271 | if (compare_types(&controlling_type, &cur_type, 0)) { |
| 5243 | if (has_match) { | 5272 | if (has_match) { |
| @@ -5501,6 +5530,8 @@ special_math_val: · 257 unmodified lines |
| 5501 | } | 5530 | } |
| 5502 | vset(&s->type, VT_LOCAL | VT_LVAL, addr); | 5531 | vset(&s->type, VT_LOCAL | VT_LVAL, addr); |
| 5503 | } | 5532 | } |
| | 5533 | if (s->f.func_noreturn) |
| | 5534 | CODE_OFF(); |
| 5504 | } else { | 5535 | } else { |
| 5505 | break; | 5536 | break; |
| 5506 | } | 5537 | } |
| @@ -5603,86 +5634,50 @@ static void expr_or(void) · 96 unmodified lines |
| 5603 | } | 5634 | } |
| 5604 | } | 5635 | } |
| 5605 | | 5636 | |
| | 5637 | static int condition_3way(void); |
| | 5638 | |
| | 5639 | static void expr_landor(void(*e_fn)(void), int e_op, int i) |
| | 5640 | { |
| | 5641 | int t = 0, cc = 1, f = 0, c; |
| | 5642 | for(;;) { |
| | 5643 | c = f ? i : condition_3way(); |
| | 5644 | if (c < 0) { |
| | 5645 | save_regs(1), cc = 0; |
| | 5646 | } else if (c != i) { |
| | 5647 | nocode_wanted++, f = 1; |
| | 5648 | } |
| | 5649 | if (tok != e_op) { |
| | 5650 | if (cc || f) { |
| | 5651 | vpop(); |
| | 5652 | vpushi(i ^ f); |
| | 5653 | gsym(t); |
| | 5654 | nocode_wanted -= f; |
| | 5655 | } else { |
| | 5656 | vseti(VT_JMP + i, gvtst(i, t)); |
| | 5657 | } |
| | 5658 | break; |
| | 5659 | } |
| | 5660 | if (c < 0) |
| | 5661 | t = gvtst(i, t); |
| | 5662 | else |
| | 5663 | vpop(); |
| | 5664 | next(); |
| | 5665 | e_fn(); |
| | 5666 | } |
| | 5667 | } |
| | 5668 | |
| 5606 | static void expr_land(void) | 5669 | static void expr_land(void) |
| 5607 | { | 5670 | { |
| 5608 | expr_or(); | 5671 | expr_or(); |
| 5609 | if (tok == TOK_LAND) { | 5672 | if (tok == TOK_LAND) |
| 5610 | int t = 0; | 5673 | expr_landor(expr_or, TOK_LAND, 1); |
| 5611 | for(;;) { | | |
| 5612 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | | |
| 5613 | gen_cast_s(VT_BOOL); | | |
| 5614 | if (vtop->c.i) { | | |
| 5615 | vpop(); | | |
| 5616 | } else { | | |
| 5617 | nocode_wanted++; | | |
| 5618 | while (tok == TOK_LAND) { | | |
| 5619 | next(); | | |
| 5620 | expr_or(); | | |
| 5621 | vpop(); | | |
| 5622 | } | | |
| 5623 | nocode_wanted--; | | |
| 5624 | if (t) | | |
| 5625 | gsym(t); | | |
| 5626 | gen_cast_s(VT_INT); | | |
| 5627 | break; | | |
| 5628 | } | | |
| 5629 | } else { | | |
| 5630 | if (!t) | | |
| 5631 | save_regs(1); | | |
| 5632 | t = gvtst(1, t); | | |
| 5633 | } | | |
| 5634 | if (tok != TOK_LAND) { | | |
| 5635 | if (t) | | |
| 5636 | vseti(VT_JMPI, t); | | |
| 5637 | else | | |
| 5638 | vpushi(1); | | |
| 5639 | break; | | |
| 5640 | } | | |
| 5641 | next(); | | |
| 5642 | expr_or(); | | |
| 5643 | } | | |
| 5644 | } | | |
| 5645 | } | 5674 | } |
| 5646 | | 5675 | |
| 5647 | static void expr_lor(void) | 5676 | static void expr_lor(void) |
| 5648 | { | 5677 | { |
| 5649 | expr_land(); | 5678 | expr_land(); |
| 5650 | if (tok == TOK_LOR) { | 5679 | if (tok == TOK_LOR) |
| 5651 | int t = 0; | 5680 | expr_landor(expr_land, TOK_LOR, 0); |
| 5652 | for(;;) { | | |
| 5653 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | | |
| 5654 | gen_cast_s(VT_BOOL); | | |
| 5655 | if (!vtop->c.i) { | | |
| 5656 | vpop(); | | |
| 5657 | } else { | | |
| 5658 | nocode_wanted++; | | |
| 5659 | while (tok == TOK_LOR) { | | |
| 5660 | next(); | | |
| 5661 | expr_land(); | | |
| 5662 | vpop(); | | |
| 5663 | } | | |
| 5664 | nocode_wanted--; | | |
| 5665 | if (t) | | |
| 5666 | gsym(t); | | |
| 5667 | gen_cast_s(VT_INT); | | |
| 5668 | break; | | |
| 5669 | } | | |
| 5670 | } else { | | |
| 5671 | if (!t) | | |
| 5672 | save_regs(1); | | |
| 5673 | t = gvtst(0, t); | | |
| 5674 | } | | |
| 5675 | if (tok != TOK_LOR) { | | |
| 5676 | if (t) | | |
| 5677 | vseti(VT_JMP, t); | | |
| 5678 | else | | |
| 5679 | vpushi(0); | | |
| 5680 | break; | | |
| 5681 | } | | |
| 5682 | next(); | | |
| 5683 | expr_land(); | | |
| 5684 | } | | |
| 5685 | } | | |
| 5686 | } | 5681 | } |
| 5687 | | 5682 | |
| 5688 | /* Assuming vtop is a value used in a conditional context | 5683 | /* Assuming vtop is a value used in a conditional context |
| @@ -5706,15 +5701,25 @@ static void expr_cond(void) · 17 unmodified lines |
| 5706 | int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g; | 5701 | int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g; |
| 5707 | SValue sv; | 5702 | SValue sv; |
| 5708 | CType type, type1, type2; | 5703 | CType type, type1, type2; |
| | 5704 | int ncw_prev; |
| 5709 | | 5705 | |
| 5710 | expr_lor(); | 5706 | expr_lor(); |
| 5711 | if (tok == '?') { | 5707 | if (tok == '?') { |
| 5712 | next(); | 5708 | next(); |
| 5713 | c = condition_3way(); | 5709 | c = condition_3way(); |
| 5714 | g = (tok == ':' && gnu_ext); | 5710 | g = (tok == ':' && gnu_ext); |
| 5715 | if (c < 0) { | 5711 | tt = 0; |
| | 5712 | if (!g) { |
| | 5713 | if (c < 0) { |
| | 5714 | save_regs(1); |
| | 5715 | tt = gvtst(1, 0); |
| | 5716 | } else { |
| | 5717 | vpop(); |
| | 5718 | } |
| | 5719 | } else if (c < 0) { |
| 5716 | /* needed to avoid having different registers saved in | 5720 | /* needed to avoid having different registers saved in |
| 5717 | each branch */ | 5721 | each branch */ |
| | 5722 | rc = RC_INT; |
| 5718 | if (is_float(vtop->type.t)) { | 5723 | if (is_float(vtop->type.t)) { |
| 5719 | rc = RC_FLOAT; | 5724 | rc = RC_FLOAT; |
| 5720 | #ifdef TCC_TARGET_X86_64 | 5725 | #ifdef TCC_TARGET_X86_64 |
| @@ -5722,20 +5727,14 @@ static void expr_cond(void) · 1 unmodified line |
| 5722 | rc = RC_ST0; | 5727 | rc = RC_ST0; |
| 5723 | } | 5728 | } |
| 5724 | #endif | 5729 | #endif |
| 5725 | } else | 5730 | } |
| 5726 | rc = RC_INT; | | |
| 5727 | gv(rc); | 5731 | gv(rc); |
| 5728 | save_regs(1); | 5732 | save_regs(1); |
| 5729 | if (g) | 5733 | gv_dup(); |
| 5730 | gv_dup(); | 5734 | tt = gvtst(0, 0); |
| 5731 | tt = gvtst(1, 0); | | |
| 5732 | | | |
| 5733 | } else { | | |
| 5734 | if (!g) | | |
| 5735 | vpop(); | | |
| 5736 | tt = 0; | | |
| 5737 | } | 5735 | } |
| 5738 | | 5736 | |
| | 5737 | ncw_prev = nocode_wanted; |
| 5739 | if (1) { | 5738 | if (1) { |
| 5740 | if (c == 0) | 5739 | if (c == 0) |
| 5741 | nocode_wanted++; | 5740 | nocode_wanted++; |
| @@ -5747,20 +5746,21 @@ static void expr_cond(void) · 5 unmodified lines |
| 5747 | type1 = vtop->type; | 5746 | type1 = vtop->type; |
| 5748 | sv = *vtop; /* save value to handle it later */ | 5747 | sv = *vtop; /* save value to handle it later */ |
| 5749 | vtop--; /* no vpop so that FP stack is not flushed */ | 5748 | vtop--; /* no vpop so that FP stack is not flushed */ |
| 5750 | skip(':'); | | |
| 5751 | | 5749 | |
| 5752 | u = 0; | 5750 | if (g) { |
| 5753 | if (c < 0) | 5751 | u = tt; |
| | 5752 | } else if (c < 0) { |
| 5754 | u = gjmp(0); | 5753 | u = gjmp(0); |
| 5755 | gsym(tt); | 5754 | gsym(tt); |
| | 5755 | } else |
| | 5756 | u = 0; |
| 5756 | | 5757 | |
| 5757 | if (c == 0) | 5758 | nocode_wanted = ncw_prev; |
| 5758 | nocode_wanted--; | | |
| 5759 | if (c == 1) | 5759 | if (c == 1) |
| 5760 | nocode_wanted++; | 5760 | nocode_wanted++; |
| | 5761 | skip(':'); |
| 5761 | expr_cond(); | 5762 | expr_cond(); |
| 5762 | if (c == 1) | 5763 | |
| 5763 | nocode_wanted--; | | |
| 5764 | | 5764 | |
| 5765 | if ((vtop->type.t & VT_BTYPE) == VT_FUNC) | 5765 | if ((vtop->type.t & VT_BTYPE) == VT_FUNC) |
| 5766 | mk_pointer(&vtop->type); | 5766 | mk_pointer(&vtop->type); |
| @@ -5771,7 +5771,6 @@ static void expr_cond(void) · 4 unmodified lines |
| 5771 | bt2 = t2 & VT_BTYPE; | 5771 | bt2 = t2 & VT_BTYPE; |
| 5772 | type.ref = NULL; | 5772 | type.ref = NULL; |
| 5773 | | 5773 | |
| 5774 | | | |
| 5775 | /* cast operands to correct type according to ISOC rules */ | 5774 | /* cast operands to correct type according to ISOC rules */ |
| 5776 | if (bt1 == VT_VOID || bt2 == VT_VOID) { | 5775 | if (bt1 == VT_VOID || bt2 == VT_VOID) { |
| 5777 | type.t = VT_VOID; /* NOTE: as an extension, we accept void on only one side */ | 5776 | type.t = VT_VOID; /* NOTE: as an extension, we accept void on only one side */ |
| @@ -5902,15 +5901,17 @@ static void expr_cond(void) · 124 unmodified lines |
| 5902 | gaddrof(); | 5901 | gaddrof(); |
| 5903 | } | 5902 | } |
| 5904 | | 5903 | |
| 5905 | if (c < 0 || islv) { | 5904 | if (c < 0) { |
| 5906 | r1 = gv(rc); | 5905 | r1 = gv(rc); |
| 5907 | move_reg(r2, r1, type.t); | 5906 | move_reg(r2, r1, type.t); |
| 5908 | vtop->r = r2; | 5907 | vtop->r = r2; |
| 5909 | gsym(tt); | 5908 | gsym(tt); |
| 5910 | if (islv) | | |
| 5911 | indir(); | | |
| 5912 | } | 5909 | } |
| | 5910 | |
| | 5911 | if (islv) |
| | 5912 | indir(); |
| 5913 | } | 5913 | } |
| | 5914 | nocode_wanted = ncw_prev; |
| 5914 | } | 5915 | } |
| 5915 | } | 5916 | } |
| 5916 | | 5917 | |
| @@ -5982,25 +5983,8 @@ ST_FUNC int expr_const(void) · 65 unmodified lines |
| 5982 | return c; | 5983 | return c; |
| 5983 | } | 5984 | } |
| 5984 | | 5985 | |
| 5985 | /* return the label token if current token is a label, otherwise | 5986 | /* ------------------------------------------------------------------------- */ |
| 5986 | return zero */ | 5987 | /* return from function */ |
| 5987 | static int is_label(void) | | |
| 5988 | { | | |
| 5989 | int last_tok; | | |
| 5990 | | | |
| 5991 | /* fast test first */ | | |
| 5992 | if (tok < TOK_UIDENT) | | |
| 5993 | return 0; | | |
| 5994 | /* no need to save tokc because tok is an identifier */ | | |
| 5995 | last_tok = tok; | | |
| 5996 | next(); | | |
| 5997 | if (tok == ':') { | | |
| 5998 | return last_tok; | | |
| 5999 | } else { | | |
| 6000 | unget_tok(last_tok); | | |
| 6001 | return 0; | | |
| 6002 | } | | |
| 6003 | } | | |
| 6004 | | 5988 | |
| 6005 | #ifndef TCC_TARGET_ARM64 | 5989 | #ifndef TCC_TARGET_ARM64 |
| 6006 | static void gfunc_return(CType *func_type) | 5990 | static void gfunc_return(CType *func_type) |
| @@ -6135,75 +6119,97 @@ static void gcase(struct case_t **base, int len, int *bsym) · 128 unmodified lines |
| 6135 | } | 6119 | } |
| 6136 | } | 6120 | } |
| 6137 | | 6121 | |
| | 6122 | /* call 'func' for each __attribute__((cleanup(func))) */ |
| | 6123 | static void block_cleanup(Sym *lcleanup, int lncleanups) |
| | 6124 | { |
| | 6125 | int jmp = 0; |
| | 6126 | Sym *g, **pg; |
| | 6127 | for (pg = &pending_gotos; (g = *pg) && g->c > lncleanups;) { |
| | 6128 | if (g->prev_tok->r & LABEL_FORWARD) { |
| | 6129 | Sym *pcl = g->next; |
| | 6130 | if (!jmp) |
| | 6131 | jmp = gjmp(0); |
| | 6132 | gsym(pcl->jnext); |
| | 6133 | try_call_scope_cleanup(lcleanup); |
| | 6134 | pcl->jnext = gjmp(0); |
| | 6135 | if (!lncleanups) |
| | 6136 | goto remove_pending; |
| | 6137 | g->c = lncleanups; |
| | 6138 | pg = &g->prev; |
| | 6139 | } else { |
| | 6140 | remove_pending: |
| | 6141 | *pg = g->prev; |
| | 6142 | sym_free(g); |
| | 6143 | } |
| | 6144 | } |
| | 6145 | gsym(jmp); |
| | 6146 | try_call_scope_cleanup(lcleanup); |
| | 6147 | current_cleanups = lcleanup; |
| | 6148 | ncleanups = lncleanups; |
| | 6149 | } |
| | 6150 | |
| | 6151 | static void check_func_return(void) |
| | 6152 | { |
| | 6153 | if ((func_vt.t & VT_BTYPE) == VT_VOID) |
| | 6154 | return; |
| | 6155 | if (!strcmp (funcname, "main") |
| | 6156 | && (func_vt.t & VT_BTYPE) == VT_INT) { |
| | 6157 | /* main returns 0 by default */ |
| | 6158 | vpushi(0); |
| | 6159 | gen_assign_cast(&func_vt); |
| | 6160 | gfunc_return(&func_vt); |
| | 6161 | } else { |
| | 6162 | tcc_warning("function might return no value: '%s'", funcname); |
| | 6163 | } |
| | 6164 | } |
| | 6165 | |
| 6138 | static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) | 6166 | static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) |
| 6139 | { | 6167 | { |
| 6140 | int a, b, c, d, cond; | 6168 | int a, b, c, d, e, t; |
| 6141 | Sym *s; | 6169 | Sym *s; |
| 6142 | | 6170 | |
| 6143 | /* generate line number info */ | | |
| 6144 | if (tcc_state->do_debug) | | |
| 6145 | tcc_debug_line(tcc_state); | | |
| 6146 | | | |
| 6147 | if (is_expr) { | 6171 | if (is_expr) { |
| 6148 | /* default return value is (void) */ | 6172 | /* default return value is (void) */ |
| 6149 | vpushi(0); | 6173 | vpushi(0); |
| 6150 | vtop->type.t = VT_VOID; | 6174 | vtop->type.t = VT_VOID; |
| 6151 | } | 6175 | } |
| 6152 | | 6176 | |
| 6153 | if (tok == TOK_IF) { | 6177 | t = tok, next(); |
| 6154 | /* if test */ | 6178 | |
| 6155 | int saved_nocode_wanted = nocode_wanted; | 6179 | if (t == TOK_IF) { |
| 6156 | next(); | | |
| 6157 | skip('('); | 6180 | skip('('); |
| 6158 | gexpr(); | 6181 | gexpr(); |
| 6159 | skip(')'); | 6182 | skip(')'); |
| 6160 | cond = condition_3way(); | 6183 | a = gvtst(1, 0); |
| 6161 | if (cond == 1) | | |
| 6162 | a = 0, vpop(); | | |
| 6163 | else | | |
| 6164 | a = gvtst(1, 0); | | |
| 6165 | if (cond == 0) | | |
| 6166 | nocode_wanted |= 0x20000000; | | |
| 6167 | block(bsym, bcl, csym, ccl, 0); | 6184 | block(bsym, bcl, csym, ccl, 0); |
| 6168 | if (cond != 1) | | |
| 6169 | nocode_wanted = saved_nocode_wanted; | | |
| 6170 | if (tok == TOK_ELSE) { | 6185 | if (tok == TOK_ELSE) { |
| 6171 | next(); | | |
| 6172 | d = gjmp(0); | 6186 | d = gjmp(0); |
| 6173 | gsym(a); | 6187 | gsym(a); |
| 6174 | if (cond == 1) | 6188 | next(); |
| 6175 | nocode_wanted |= 0x20000000; | | |
| 6176 | block(bsym, bcl, csym, ccl, 0); | 6189 | block(bsym, bcl, csym, ccl, 0); |
| 6177 | gsym(d); /* patch else jmp */ | 6190 | gsym(d); /* patch else jmp */ |
| 6178 | if (cond != 0) | 6191 | } else { |
| 6179 | nocode_wanted = saved_nocode_wanted; | | |
| 6180 | } else | | |
| 6181 | gsym(a); | 6192 | gsym(a); |
| 6182 | } else if (tok == TOK_WHILE) { | 6193 | } |
| 6183 | int saved_nocode_wanted; | 6194 | |
| 6184 | nocode_wanted &= ~0x20000000; | 6195 | } else if (t == TOK_WHILE) { |
| 6185 | next(); | 6196 | d = gind(); |
| 6186 | d = ind; | | |
| 6187 | vla_sp_restore(); | 6197 | vla_sp_restore(); |
| 6188 | skip('('); | 6198 | skip('('); |
| 6189 | gexpr(); | 6199 | gexpr(); |
| 6190 | skip(')'); | 6200 | skip(')'); |
| 6191 | a = gvtst(1, 0); | 6201 | a = gvtst(1, 0); |
| 6192 | b = 0; | 6202 | b = 0; |
| 6193 | ++local_scope; | | |
| 6194 | saved_nocode_wanted = nocode_wanted; | | |
| 6195 | block(&a, current_cleanups, &b, current_cleanups, 0); | 6203 | block(&a, current_cleanups, &b, current_cleanups, 0); |
| 6196 | nocode_wanted = saved_nocode_wanted; | | |
| 6197 | --local_scope; | | |
| 6198 | gjmp_addr(d); | 6204 | gjmp_addr(d); |
| 6199 | gsym(a); | | |
| 6200 | gsym_addr(b, d); | 6205 | gsym_addr(b, d); |
| 6201 | } else if (tok == '{') { | 6206 | gsym(a); |
| | 6207 | |
| | 6208 | } else if (t == '{') { |
| 6202 | Sym *llabel, *lcleanup; | 6209 | Sym *llabel, *lcleanup; |
| 6203 | int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope; | 6210 | int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope; |
| 6204 | int lncleanups = ncleanups; | 6211 | int lncleanups = ncleanups; |
| 6205 | | 6212 | |
| 6206 | next(); | | |
| 6207 | /* record local declaration stack position */ | 6213 | /* record local declaration stack position */ |
| 6208 | s = local_stack; | 6214 | s = local_stack; |
| 6209 | llabel = local_label_stack; | 6215 | llabel = local_label_stack; |
| @@ -6212,25 +6218,18 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 2 unmodified lines |
| 6212 | | 6218 | |
| 6213 | /* handle local labels declarations */ | 6219 | /* handle local labels declarations */ |
| 6214 | while (tok == TOK_LABEL) { | 6220 | while (tok == TOK_LABEL) { |
| 6215 | next(); | 6221 | do { |
| 6216 | for(;;) { | 6222 | next(); |
| 6217 | if (tok < TOK_UIDENT) | 6223 | if (tok < TOK_UIDENT) |
| 6218 | expect("label identifier"); | 6224 | expect("label identifier"); |
| 6219 | label_push(&local_label_stack, tok, LABEL_DECLARED); | 6225 | label_push(&local_label_stack, tok, LABEL_DECLARED); |
| 6220 | next(); | 6226 | next(); |
| 6221 | if (tok == ',') { | 6227 | } while (tok == ','); |
| 6222 | next(); | 6228 | skip(';'); |
| 6223 | } else { | | |
| 6224 | skip(';'); | | |
| 6225 | break; | | |
| 6226 | } | | |
| 6227 | } | | |
| 6228 | } | 6229 | } |
| | 6230 | |
| 6229 | while (tok != '}') { | 6231 | while (tok != '}') { |
| 6230 | if ((a = is_label())) | 6232 | decl(VT_LOCAL); |
| 6231 | unget_tok(a); | | |
| 6232 | else | | |
| 6233 | decl(VT_LOCAL); | | |
| 6234 | if (tok != '}') { | 6233 | if (tok != '}') { |
| 6235 | if (is_expr) | 6234 | if (is_expr) |
| 6236 | vpop(); | 6235 | vpop(); |
| @@ -6238,39 +6237,12 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line |
| 6238 | } | 6237 | } |
| 6239 | } | 6238 | } |
| 6240 | | 6239 | |
| 6241 | if (current_cleanups != lcleanup) { | 6240 | if (current_cleanups != lcleanup) |
| 6242 | int jmp = 0; | 6241 | block_cleanup(lcleanup, lncleanups); |
| 6243 | Sym *g, **pg; | | |
| 6244 | | | |
| 6245 | for (pg = &pending_gotos; (g = *pg) && g->c > lncleanups;) | | |
| 6246 | if (g->prev_tok->r & LABEL_FORWARD) { | | |
| 6247 | Sym *pcl = g->next; | | |
| 6248 | if (!jmp) | | |
| 6249 | jmp = gjmp(0); | | |
| 6250 | gsym(pcl->jnext); | | |
| 6251 | try_call_scope_cleanup(lcleanup); | | |
| 6252 | pcl->jnext = gjmp(0); | | |
| 6253 | if (!lncleanups) | | |
| 6254 | goto remove_pending; | | |
| 6255 | g->c = lncleanups; | | |
| 6256 | pg = &g->prev; | | |
| 6257 | } else { | | |
| 6258 | remove_pending: | | |
| 6259 | *pg = g->prev; | | |
| 6260 | sym_free(g); | | |
| 6261 | } | | |
| 6262 | gsym(jmp); | | |
| 6263 | if (!nocode_wanted) { | | |
| 6264 | try_call_scope_cleanup(lcleanup); | | |
| 6265 | } | | |
| 6266 | } | | |
| 6267 | | 6242 | |
| 6268 | current_cleanups = lcleanup; | | |
| 6269 | ncleanups = lncleanups; | | |
| 6270 | /* pop locally defined labels */ | 6243 | /* pop locally defined labels */ |
| 6271 | label_pop(&local_label_stack, llabel, is_expr); | 6244 | label_pop(&local_label_stack, llabel, is_expr); |
| 6272 | /* pop locally defined symbols */ | 6245 | |
| 6273 | --local_scope; | | |
| 6274 | /* In the is_expr case (a statement expression is finished here), | 6246 | /* In the is_expr case (a statement expression is finished here), |
| 6275 | vtop might refer to symbols on the local_stack. Either via the | 6247 | vtop might refer to symbols on the local_stack. Either via the |
| 6276 | type or via vtop->sym. We can't pop those nor any that in turn | 6248 | type or via vtop->sym. We can't pop those nor any that in turn |
| @@ -6278,6 +6250,8 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line |
| 6278 | any symbols in that case; some upper level call to block() will | 6250 | any symbols in that case; some upper level call to block() will |
| 6279 | do that. We do have to remove such symbols from the lookup | 6251 | do that. We do have to remove such symbols from the lookup |
| 6280 | tables, though. sym_pop will do that. */ | 6252 | tables, though. sym_pop will do that. */ |
| | 6253 | |
| | 6254 | /* pop locally defined symbols */ |
| 6281 | sym_pop(&local_stack, s, is_expr); | 6255 | sym_pop(&local_stack, s, is_expr); |
| 6282 | | 6256 | |
| 6283 | /* Pop VLA frames and restore stack pointer if required */ | 6257 | /* Pop VLA frames and restore stack pointer if required */ |
| @@ -6287,52 +6261,49 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 3 unmodified lines |
| 6287 | } | 6261 | } |
| 6288 | vlas_in_scope = saved_vlas_in_scope; | 6262 | vlas_in_scope = saved_vlas_in_scope; |
| 6289 | | 6263 | |
| | 6264 | if (0 == --local_scope && !nocode_wanted) |
| | 6265 | check_func_return(); |
| 6290 | next(); | 6266 | next(); |
| 6291 | } else if (tok == TOK_RETURN) { | 6267 | |
| 6292 | next(); | 6268 | } else if (t == TOK_RETURN) { |
| 6293 | if (tok != ';') { | 6269 | a = tok != ';'; |
| 6294 | gexpr(); | 6270 | b = (func_vt.t & VT_BTYPE) != VT_VOID; |
| 6295 | gen_assign_cast(&func_vt); | 6271 | if (a) |
| 6296 | try_call_scope_cleanup(NULL); | 6272 | gexpr(), gen_assign_cast(&func_vt); |
| 6297 | if ((func_vt.t & VT_BTYPE) == VT_VOID) | 6273 | try_call_scope_cleanup(NULL); |
| 6298 | vtop--; | 6274 | if (a && b) |
| 6299 | else | 6275 | gfunc_return(&func_vt); |
| 6300 | gfunc_return(&func_vt); | 6276 | else if (a) |
| 6301 | } else { | 6277 | vtop--; |
| 6302 | try_call_scope_cleanup(NULL); | 6278 | else if (b) |
| 6303 | } | 6279 | tcc_warning("'return' with no value."); |
| 6304 | skip(';'); | 6280 | skip(';'); |
| 6305 | /* jump unless last stmt in top-level block */ | 6281 | /* jump unless last stmt in top-level block */ |
| 6306 | if (tok != '}' || local_scope != 1) | 6282 | if (tok != '}' || local_scope != 1) |
| 6307 | rsym = gjmp(rsym); | 6283 | rsym = gjmp(rsym); |
| 6308 | nocode_wanted |= 0x20000000; | 6284 | CODE_OFF(); |
| 6309 | } else if (tok == TOK_BREAK) { | 6285 | |
| | 6286 | } else if (t == TOK_BREAK) { |
| 6310 | /* compute jump */ | 6287 | /* compute jump */ |
| 6311 | if (!bsym) | 6288 | if (!bsym) |
| 6312 | tcc_error("cannot break"); | 6289 | tcc_error("cannot break"); |
| 6313 | try_call_scope_cleanup(bcl); | 6290 | try_call_scope_cleanup(bcl); |
| 6314 | *bsym = gjmp(*bsym); | 6291 | *bsym = gjmp(*bsym); |
| 6315 | next(); | | |
| 6316 | skip(';'); | 6292 | skip(';'); |
| 6317 | nocode_wanted |= 0x20000000; | 6293 | |
| 6318 | } else if (tok == TOK_CONTINUE) { | 6294 | } else if (t == TOK_CONTINUE) { |
| 6319 | /* compute jump */ | 6295 | /* compute jump */ |
| 6320 | if (!csym) | 6296 | if (!csym) |
| 6321 | tcc_error("cannot continue"); | 6297 | tcc_error("cannot continue"); |
| 6322 | try_call_scope_cleanup(ccl); | 6298 | try_call_scope_cleanup(ccl); |
| 6323 | vla_sp_restore_root(); | 6299 | vla_sp_restore_root(); |
| 6324 | *csym = gjmp(*csym); | 6300 | *csym = gjmp(*csym); |
| 6325 | next(); | | |
| 6326 | skip(';'); | 6301 | skip(';'); |
| 6327 | nocode_wanted |= 0x20000000; | 6302 | |
| 6328 | } else if (tok == TOK_FOR) { | 6303 | } else if (t == TOK_FOR) { |
| 6329 | int e; | | |
| 6330 | int saved_nocode_wanted; | | |
| 6331 | Sym *lcleanup = current_cleanups; | 6304 | Sym *lcleanup = current_cleanups; |
| 6332 | int lncleanups = ncleanups; | 6305 | int lncleanups = ncleanups; |
| 6333 | | 6306 | |
| 6334 | nocode_wanted &= ~0x20000000; | | |
| 6335 | next(); | | |
| 6336 | skip('('); | 6307 | skip('('); |
| 6337 | s = local_stack; | 6308 | s = local_stack; |
| 6338 | ++local_scope; | 6309 | ++local_scope; |
| @@ -6345,11 +6316,9 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 6 unmodified lines |
| 6345 | } | 6316 | } |
| 6346 | } | 6317 | } |
| 6347 | skip(';'); | 6318 | skip(';'); |
| 6348 | d = ind; | 6319 | a = b = 0; |
| 6349 | c = ind; | 6320 | c = d = gind(); |
| 6350 | vla_sp_restore(); | 6321 | vla_sp_restore(); |
| 6351 | a = 0; | | |
| 6352 | b = 0; | | |
| 6353 | if (tok != ';') { | 6322 | if (tok != ';') { |
| 6354 | gexpr(); | 6323 | gexpr(); |
| 6355 | a = gvtst(1, 0); | 6324 | a = gvtst(1, 0); |
| @@ -6357,55 +6326,43 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line |
| 6357 | skip(';'); | 6326 | skip(';'); |
| 6358 | if (tok != ')') { | 6327 | if (tok != ')') { |
| 6359 | e = gjmp(0); | 6328 | e = gjmp(0); |
| 6360 | c = ind; | 6329 | d = gind(); |
| 6361 | vla_sp_restore(); | 6330 | vla_sp_restore(); |
| 6362 | gexpr(); | 6331 | gexpr(); |
| 6363 | vpop(); | 6332 | vpop(); |
| 6364 | gjmp_addr(d); | 6333 | gjmp_addr(c); |
| 6365 | gsym(e); | 6334 | gsym(e); |
| 6366 | } | 6335 | } |
| 6367 | skip(')'); | 6336 | skip(')'); |
| 6368 | saved_nocode_wanted = nocode_wanted; | | |
| 6369 | block(&a, current_cleanups, &b, current_cleanups, 0); | 6337 | block(&a, current_cleanups, &b, current_cleanups, 0); |
| 6370 | nocode_wanted = saved_nocode_wanted; | 6338 | gjmp_addr(d); |
| 6371 | gjmp_addr(c); | 6339 | gsym_addr(b, d); |
| 6372 | gsym(a); | 6340 | gsym(a); |
| 6373 | gsym_addr(b, c); | | |
| 6374 | --local_scope; | 6341 | --local_scope; |
| 6375 | try_call_scope_cleanup(lcleanup); | 6342 | try_call_scope_cleanup(lcleanup); |
| 6376 | ncleanups = lncleanups; | 6343 | ncleanups = lncleanups; |
| 6377 | current_cleanups = lcleanup; | 6344 | current_cleanups = lcleanup; |
| 6378 | sym_pop(&local_stack, s, 0); | 6345 | sym_pop(&local_stack, s, 0); |
| 6379 | | 6346 | |
| 6380 | } else | 6347 | } else if (t == TOK_DO) { |
| 6381 | if (tok == TOK_DO) { | 6348 | a = b = 0; |
| 6382 | int saved_nocode_wanted; | 6349 | d = gind(); |
| 6383 | nocode_wanted &= ~0x20000000; | | |
| 6384 | next(); | | |
| 6385 | a = 0; | | |
| 6386 | b = 0; | | |
| 6387 | d = ind; | | |
| 6388 | vla_sp_restore(); | 6350 | vla_sp_restore(); |
| 6389 | saved_nocode_wanted = nocode_wanted; | | |
| 6390 | block(&a, current_cleanups, &b, current_cleanups, 0); | 6351 | block(&a, current_cleanups, &b, current_cleanups, 0); |
| | 6352 | gsym(b); |
| 6391 | skip(TOK_WHILE); | 6353 | skip(TOK_WHILE); |
| 6392 | skip('('); | 6354 | skip('('); |
| 6393 | gsym(b); | | |
| 6394 | if (b) | | |
| 6395 | nocode_wanted = saved_nocode_wanted; | | |
| 6396 | gexpr(); | 6355 | gexpr(); |
| | 6356 | skip(')'); |
| | 6357 | skip(';'); |
| 6397 | c = gvtst(0, 0); | 6358 | c = gvtst(0, 0); |
| 6398 | gsym_addr(c, d); | 6359 | gsym_addr(c, d); |
| 6399 | nocode_wanted = saved_nocode_wanted; | | |
| 6400 | skip(')'); | | |
| 6401 | gsym(a); | 6360 | gsym(a); |
| 6402 | skip(';'); | 6361 | |
| 6403 | } else | 6362 | } else if (t == TOK_SWITCH) { |
| 6404 | if (tok == TOK_SWITCH) { | | |
| 6405 | struct switch_t *saved, sw; | 6363 | struct switch_t *saved, sw; |
| 6406 | int saved_nocode_wanted = nocode_wanted; | | |
| 6407 | SValue switchval; | 6364 | SValue switchval; |
| 6408 | next(); | 6365 | |
| 6409 | skip('('); | 6366 | skip('('); |
| 6410 | gexpr(); | 6367 | gexpr(); |
| 6411 | skip(')'); | 6368 | skip(')'); |
| @@ -6416,7 +6373,6 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 4 unmodified lines |
| 6416 | saved = cur_switch; | 6373 | saved = cur_switch; |
| 6417 | cur_switch = &sw; | 6374 | cur_switch = &sw; |
| 6418 | block(&a, current_cleanups, csym, ccl, 0); | 6375 | block(&a, current_cleanups, csym, ccl, 0); |
| 6419 | nocode_wanted = saved_nocode_wanted; | | |
| 6420 | a = gjmp(a); /* add implicit break */ | 6376 | a = gjmp(a); /* add implicit break */ |
| 6421 | /* case lookup */ | 6377 | /* case lookup */ |
| 6422 | gsym(b); | 6378 | gsym(b); |
| @@ -6437,13 +6393,11 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 14 unmodified lines |
| 6437 | cur_switch = saved; | 6393 | cur_switch = saved; |
| 6438 | /* break label */ | 6394 | /* break label */ |
| 6439 | gsym(a); | 6395 | gsym(a); |
| 6440 | } else | 6396 | |
| 6441 | if (tok == TOK_CASE) { | 6397 | } else if (t == TOK_CASE) { |
| 6442 | struct case_t *cr = tcc_malloc(sizeof(struct case_t)); | 6398 | struct case_t *cr = tcc_malloc(sizeof(struct case_t)); |
| 6443 | if (!cur_switch) | 6399 | if (!cur_switch) |
| 6444 | expect("switch"); | 6400 | expect("switch"); |
| 6445 | nocode_wanted &= ~0x20000000; | | |
| 6446 | next(); | | |
| 6447 | cr->v1 = cr->v2 = expr_const64(); | 6401 | cr->v1 = cr->v2 = expr_const64(); |
| 6448 | if (gnu_ext && tok == TOK_DOTS) { | 6402 | if (gnu_ext && tok == TOK_DOTS) { |
| 6449 | next(); | 6403 | next(); |
| @@ -6451,25 +6405,23 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line |
| 6451 | if (cr->v2 < cr->v1) | 6405 | if (cr->v2 < cr->v1) |
| 6452 | tcc_warning("empty case range"); | 6406 | tcc_warning("empty case range"); |
| 6453 | } | 6407 | } |
| 6454 | cr->sym = ind; | 6408 | cr->sym = gind(); |
| 6455 | dynarray_add(&cur_switch->p, &cur_switch->n, cr); | 6409 | dynarray_add(&cur_switch->p, &cur_switch->n, cr); |
| 6456 | skip(':'); | 6410 | skip(':'); |
| 6457 | is_expr = 0; | 6411 | is_expr = 0; |
| 6458 | goto block_after_label; | 6412 | goto block_after_label; |
| 6459 | } else | 6413 | |
| 6460 | if (tok == TOK_DEFAULT) { | 6414 | } else if (t == TOK_DEFAULT) { |
| 6461 | next(); | | |
| 6462 | skip(':'); | | |
| 6463 | if (!cur_switch) | 6415 | if (!cur_switch) |
| 6464 | expect("switch"); | 6416 | expect("switch"); |
| 6465 | if (cur_switch->def_sym) | 6417 | if (cur_switch->def_sym) |
| 6466 | tcc_error("too many 'default'"); | 6418 | tcc_error("too many 'default'"); |
| 6467 | cur_switch->def_sym = ind; | 6419 | cur_switch->def_sym = gind(); |
| | 6420 | skip(':'); |
| 6468 | is_expr = 0; | 6421 | is_expr = 0; |
| 6469 | goto block_after_label; | 6422 | goto block_after_label; |
| 6470 | } else | 6423 | |
| 6471 | if (tok == TOK_GOTO) { | 6424 | } else if (t == TOK_GOTO) { |
| 6472 | next(); | | |
| 6473 | if (tok == '*' && gnu_ext) { | 6425 | if (tok == '*' && gnu_ext) { |
| 6474 | /* computed goto */ | 6426 | /* computed goto */ |
| 6475 | next(); | 6427 | next(); |
| @@ -6500,18 +6452,20 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 24 unmodified lines |
| 6500 | gjmp_addr(s->jnext); | 6452 | gjmp_addr(s->jnext); |
| 6501 | } | 6453 | } |
| 6502 | next(); | 6454 | next(); |
| 6503 | } else { | 6455 | |
| | 6456 | } else { |
| 6504 | expect("label identifier"); | 6457 | expect("label identifier"); |
| 6505 | } | 6458 | } |
| 6506 | skip(';'); | 6459 | skip(';'); |
| 6507 | } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { | 6460 | |
| | 6461 | } else if (t == TOK_ASM1 || t == TOK_ASM2 || t == TOK_ASM3) { |
| 6508 | asm_instr(); | 6462 | asm_instr(); |
| | 6463 | |
| 6509 | } else { | 6464 | } else { |
| 6510 | b = is_label(); | 6465 | if (tok == ':' && t >= TOK_UIDENT) { |
| 6511 | if (b) { | | |
| 6512 | /* label case */ | 6466 | /* label case */ |
| 6513 | next(); | 6467 | next(); |
| 6514 | s = label_find(b); | 6468 | s = label_find(t); |
| 6515 | if (s) { | 6469 | if (s) { |
| 6516 | if (s->r == LABEL_DEFINED) | 6470 | if (s->r == LABEL_DEFINED) |
| 6517 | tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL)); | 6471 | tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL)); |
| @@ -6524,14 +6478,14 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 6 unmodified lines |
| 6524 | } else | 6478 | } else |
| 6525 | gsym(s->jnext); | 6479 | gsym(s->jnext); |
| 6526 | } else { | 6480 | } else { |
| 6527 | s = label_push(&global_label_stack, b, LABEL_DEFINED); | 6481 | s = label_push(&global_label_stack, t, LABEL_DEFINED); |
| 6528 | } | 6482 | } |
| 6529 | s->jnext = ind; | 6483 | s->jnext = gind(); |
| 6530 | s->cleanupstate = current_cleanups; | 6484 | s->cleanupstate = current_cleanups; |
| | 6485 | |
| | 6486 | block_after_label: |
| 6531 | vla_sp_restore(); | 6487 | vla_sp_restore(); |
| 6532 | /* we accept this, but it is a mistake */ | 6488 | /* we accept this, but it is a mistake */ |
| 6533 | block_after_label: | | |
| 6534 | nocode_wanted &= ~0x20000000; | | |
| 6535 | if (tok == '}') { | 6489 | if (tok == '}') { |
| 6536 | tcc_warning("deprecated use of label at end of compound statement"); | 6490 | tcc_warning("deprecated use of label at end of compound statement"); |
| 6537 | } else { | 6491 | } else { |
| @@ -6539,9 +6493,11 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line |
| 6539 | vpop(); | 6493 | vpop(); |
| 6540 | block(bsym, bcl, csym, ccl, is_expr); | 6494 | block(bsym, bcl, csym, ccl, is_expr); |
| 6541 | } | 6495 | } |
| | 6496 | |
| 6542 | } else { | 6497 | } else { |
| 6543 | /* expression case */ | 6498 | /* expression case */ |
| 6544 | if (tok != ';') { | 6499 | if (t != ';') { |
| | 6500 | unget_tok(t); |
| 6545 | if (is_expr) { | 6501 | if (is_expr) { |
| 6546 | vpop(); | 6502 | vpop(); |
| 6547 | gexpr(); | 6503 | gexpr(); |
| @@ -6549,8 +6505,8 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line |
| 6549 | gexpr(); | 6505 | gexpr(); |
| 6550 | vpop(); | 6506 | vpop(); |
| 6551 | } | 6507 | } |
| | 6508 | skip(';'); |
| 6552 | } | 6509 | } |
| 6553 | skip(';'); | | |
| 6554 | } | 6510 | } |
| 6555 | } | 6511 | } |
| 6556 | } | 6512 | } |
| @@ -6661,10 +6617,17 @@ static int decl_designator(CType *type, Section *sec, unsigned long c, · 104 unmodified lines |
| 6661 | | 6617 | |
| 6662 | elem_size = 0; | 6618 | elem_size = 0; |
| 6663 | nb_elems = 1; | 6619 | nb_elems = 1; |
| | 6620 | |
| 6664 | if (flags & DIF_HAVE_ELEM) | 6621 | if (flags & DIF_HAVE_ELEM) |
| 6665 | goto no_designator; | 6622 | goto no_designator; |
| 6666 | if (gnu_ext && (l = is_label()) != 0) | 6623 | |
| 6667 | goto struct_field; | 6624 | if (gnu_ext && tok >= TOK_UIDENT) { |
| | 6625 | l = tok, next(); |
| | 6626 | if (tok == ':') |
| | 6627 | goto struct_field; |
| | 6628 | unget_tok(l); |
| | 6629 | } |
| | 6630 | |
| 6668 | /* NOTE: we only support ranges for last designator */ | 6631 | /* NOTE: we only support ranges for last designator */ |
| 6669 | while (nb_elems == 1 && (tok == '[' || tok == '.')) { | 6632 | while (nb_elems == 1 && (tok == '[' || tok == '.')) { |
| 6670 | if (tok == '[') { | 6633 | if (tok == '[') { |
| @@ -7413,19 +7376,10 @@ static void gen_function(Sym *sym) · 742 unmodified lines |
| 7413 | gfunc_prolog(&sym->type); | 7376 | gfunc_prolog(&sym->type); |
| 7414 | reset_local_scope(); | 7377 | reset_local_scope(); |
| 7415 | rsym = 0; | 7378 | rsym = 0; |
| 7416 | clear_temp_local_var_list(); | 7379 | clear_temp_local_var_list(); |
| 7417 | block(NULL, NULL, NULL, NULL, 0); | 7380 | block(NULL, NULL, NULL, NULL, 0); |
| 7418 | if (!(nocode_wanted & 0x20000000) | | |
| 7419 | && ((func_vt.t & VT_BTYPE) == VT_INT) | | |
| 7420 | && !strcmp (funcname, "main")) | | |
| 7421 | { | | |
| 7422 | nocode_wanted = 0; | | |
| 7423 | vpushi(0); | | |
| 7424 | gen_assign_cast(&func_vt); | | |
| 7425 | gfunc_return(&func_vt); | | |
| 7426 | } | | |
| 7427 | nocode_wanted = 0; | | |
| 7428 | gsym(rsym); | 7381 | gsym(rsym); |
| | 7382 | nocode_wanted = 0; |
| 7429 | gfunc_epilog(); | 7383 | gfunc_epilog(); |
| 7430 | cur_text_section->data_offset = ind; | 7384 | cur_text_section->data_offset = ind; |
| 7431 | label_pop(&global_label_stack, NULL, 0); | 7385 | label_pop(&global_label_stack, NULL, 0); |
| @@ -7746,3 +7700,6 @@ static void decl(int l) · 314 unmodified lines |
| 7746 | } | 7700 | } |
| 7747 | | 7701 | |
| 7748 | /* ------------------------------------------------------------------------- */ | 7702 | /* ------------------------------------------------------------------------- */ |
| | 7703 | #undef gjmp_addr |
| | 7704 | #undef gjmp |
| | 7705 | /* ------------------------------------------------------------------------- */ |