| @@ -69,6 +69,7 @@ ST_DATA struct switch_t { · 68 unmodified lines |
| 69 | 69 | } *cur_switch; /* current switch */ |
| 70 | 70 | |
| 71 | 71 | /* ------------------------------------------------------------------------- */ |
| 72 | + |
| 72 | 73 | static void gen_cast(CType *type); |
| 73 | 74 | static inline CType *pointed_type(CType *type); |
| 74 | 75 | static int is_compatible_types(CType *type1, CType *type2); |
| @@ -322,11 +323,16 @@ ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, · 247 unmodified lines |
| 322 | 323 | addr_t addend) |
| 323 | 324 | { |
| 324 | 325 | int c = 0; |
| 326 | + |
| 327 | + if (nocode_wanted && s == cur_text_section) |
| 328 | + return; |
| 329 | + |
| 325 | 330 | if (sym) { |
| 326 | 331 | if (0 == sym->c) |
| 327 | 332 | put_extern_sym(sym, NULL, 0, 0); |
| 328 | 333 | c = sym->c; |
| 329 | 334 | } |
| 335 | + |
| 330 | 336 | /* now we can add ELF relocation info */ |
| 331 | 337 | put_elf_reloca(symtab_section, s, offset, type, c, addend); |
| 332 | 338 | } |
| @@ -774,6 +780,8 @@ ST_FUNC void save_reg_upstack(int r, int n) · 441 unmodified lines |
| 774 | 780 | |
| 775 | 781 | if ((r &= VT_VALMASK) >= VT_CONST) |
| 776 | 782 | return; |
| 783 | + if (nocode_wanted) |
| 784 | + return; |
| 777 | 785 | |
| 778 | 786 | /* modify all stack values */ |
| 779 | 787 | saved = 0; |
| @@ -865,6 +873,8 @@ ST_FUNC int get_reg(int rc) · 85 unmodified lines |
| 865 | 873 | /* find a free register */ |
| 866 | 874 | for(r=0;r<NB_REGS;r++) { |
| 867 | 875 | if (reg_classes[r] & rc) { |
| 876 | + if (nocode_wanted) |
| 877 | + return r; |
| 868 | 878 | for(p=vstack;p<=vtop;p++) { |
| 869 | 879 | if ((p->r & VT_VALMASK) == r || |
| 870 | 880 | (p->r2 & VT_VALMASK) == r) |
| @@ -913,7 +923,7 @@ static void move_reg(int r, int s, int t) · 42 unmodified lines |
| 913 | 923 | /* get address of vtop (vtop MUST BE an lvalue) */ |
| 914 | 924 | ST_FUNC void gaddrof(void) |
| 915 | 925 | { |
| 916 | | − if (vtop->r & VT_REF && !nocode_wanted) |
| 926 | + if (vtop->r & VT_REF) |
| 917 | 927 | gv(RC_INT); |
| 918 | 928 | vtop->r &= ~VT_LVAL; |
| 919 | 929 | /* tricky: if saved lvalue, then we can go back to lvalue */ |
| @@ -1317,7 +1327,7 @@ ST_FUNC void vpop(void) · 397 unmodified lines |
| 1317 | 1327 | v = vtop->r & VT_VALMASK; |
| 1318 | 1328 | #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) |
| 1319 | 1329 | /* for x86, we need to pop the FP stack */ |
| 1320 | | − if (v == TREG_ST0 && !nocode_wanted) { |
| 1330 | + if (v == TREG_ST0) { |
| 1321 | 1331 | o(0xd8dd); /* fstp %st(0) */ |
| 1322 | 1332 | } else |
| 1323 | 1333 | #endif |
| @@ -1607,7 +1617,7 @@ static void gen_opl(int op) · 283 unmodified lines |
| 1607 | 1617 | b = gvtst(0, 0); |
| 1608 | 1618 | } else { |
| 1609 | 1619 | #if defined(TCC_TARGET_I386) |
| 1610 | | − b = psym(0x850f, 0); |
| 1620 | + b = gjmp2(0x850f, 0); |
| 1611 | 1621 | #elif defined(TCC_TARGET_ARM) |
| 1612 | 1622 | b = ind; |
| 1613 | 1623 | o(0x1A000000 | encbranch(ind, 0, 1)); |
| @@ -1789,23 +1799,12 @@ static void gen_opic(int op) · 175 unmodified lines |
| 1789 | 1799 | vtop->c.i = l2; |
| 1790 | 1800 | } else { |
| 1791 | 1801 | general_case: |
| 1792 | | − if (!nocode_wanted) { |
| 1793 | 1802 | /* call low level op generator */ |
| 1794 | 1803 | if (t1 == VT_LLONG || t2 == VT_LLONG || |
| 1795 | 1804 | (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR))) |
| 1796 | 1805 | gen_opl(op); |
| 1797 | 1806 | else |
| 1798 | 1807 | gen_opi(op); |
| 1799 | | − } else { |
| 1800 | | − vtop--; |
| 1801 | | − /* Ensure vtop isn't marked VT_CONST in case something |
| 1802 | | − up our callchain is interested in const-ness of the |
| 1803 | | − expression. Also make it a non-LVAL if it was, |
| 1804 | | − so that further code can't accidentally generate |
| 1805 | | − a deref (happen only for buggy uses of e.g. |
| 1806 | | − gv() under nocode_wanted). */ |
| 1807 | | − vtop->r &= ~(VT_VALMASK | VT_LVAL); |
| 1808 | | − } |
| 1809 | 1808 | } |
| 1810 | 1809 | } |
| 1811 | 1810 | } |
| @@ -1866,11 +1865,7 @@ static void gen_opif(int op) · 54 unmodified lines |
| 1866 | 1865 | vtop--; |
| 1867 | 1866 | } else { |
| 1868 | 1867 | general_case: |
| 1869 | | − if (!nocode_wanted) { |
| 1870 | | − gen_opf(op); |
| 1871 | | − } else { |
| 1872 | | − vtop--; |
| 1873 | | − } |
| 1868 | + gen_opf(op); |
| 1874 | 1869 | } |
| 1875 | 1870 | } |
| 1876 | 1871 | |
| @@ -2149,7 +2144,7 @@ redo: · 272 unmodified lines |
| 2149 | 2144 | } |
| 2150 | 2145 | } |
| 2151 | 2146 | // Make sure that we have converted to an rvalue: |
| 2152 | | − if (vtop->r & VT_LVAL && !nocode_wanted) |
| 2147 | + if (vtop->r & VT_LVAL) |
| 2153 | 2148 | gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT); |
| 2154 | 2149 | } |
| 2155 | 2150 | |
| @@ -2255,7 +2250,7 @@ static void gen_cast(CType *type) · 99 unmodified lines |
| 2255 | 2250 | } |
| 2256 | 2251 | |
| 2257 | 2252 | /* bitfields first get cast to ints */ |
| 2258 | | − if (vtop->type.t & VT_BITFIELD && !nocode_wanted) { |
| 2253 | + if (vtop->type.t & VT_BITFIELD) { |
| 2259 | 2254 | gv(RC_INT); |
| 2260 | 2255 | } |
| 2261 | 2256 | |
| @@ -2331,7 +2326,7 @@ static void gen_cast(CType *type) · 69 unmodified lines |
| 2331 | 2326 | } else if (p && dbt == VT_BOOL) { |
| 2332 | 2327 | vtop->r = VT_CONST; |
| 2333 | 2328 | vtop->c.i = 1; |
| 2334 | | − } else if (!nocode_wanted) { |
| 2329 | + } else { |
| 2335 | 2330 | /* non constant case: generate code */ |
| 2336 | 2331 | if (sf && df) { |
| 2337 | 2332 | /* convert from fp to fp */ |
| @@ -2883,7 +2878,6 @@ ST_FUNC void vstore(void) · 545 unmodified lines |
| 2883 | 2878 | /* if structure, only generate pointer */ |
| 2884 | 2879 | /* structure assignment : generate memcpy */ |
| 2885 | 2880 | /* XXX: optimize if small size */ |
| 2886 | | − if (!nocode_wanted) { |
| 2887 | 2881 | size = type_size(&vtop->type, &align); |
| 2888 | 2882 | |
| 2889 | 2883 | /* destination */ |
| @@ -2910,10 +2904,7 @@ ST_FUNC void vstore(void) · 20 unmodified lines |
| 2910 | 2904 | /* type size */ |
| 2911 | 2905 | vpushi(size); |
| 2912 | 2906 | gfunc_call(3); |
| 2913 | | − } else { |
| 2914 | | − vswap(); |
| 2915 | | − vpop(); |
| 2916 | | − } |
| 2907 | + |
| 2917 | 2908 | /* leave source on stack */ |
| 2918 | 2909 | } else if (ft & VT_BITFIELD) { |
| 2919 | 2910 | /* bitfield store handling */ |
| @@ -2961,7 +2952,6 @@ ST_FUNC void vstore(void) · 41 unmodified lines |
| 2961 | 2952 | vpop(); |
| 2962 | 2953 | |
| 2963 | 2954 | } else { |
| 2964 | | − if (!nocode_wanted) { |
| 2965 | 2955 | #ifdef CONFIG_TCC_BCHECK |
| 2966 | 2956 | /* bound check case */ |
| 2967 | 2957 | if (vtop[-1].r & VT_MUSTBOUND) { |
| @@ -3020,7 +3010,7 @@ ST_FUNC void vstore(void) · 52 unmodified lines |
| 3020 | 3010 | } else { |
| 3021 | 3011 | store(r, vtop - 1); |
| 3022 | 3012 | } |
| 3023 | | − } |
| 3013 | + |
| 3024 | 3014 | vswap(); |
| 3025 | 3015 | vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ |
| 3026 | 3016 | vtop->r |= delayed_cast; |
| @@ -3033,10 +3023,7 @@ ST_FUNC void inc(int post, int c) · 6 unmodified lines |
| 3033 | 3023 | test_lvalue(); |
| 3034 | 3024 | vdup(); /* save lvalue */ |
| 3035 | 3025 | if (post) { |
| 3036 | | − if (!nocode_wanted) |
| 3037 | | − gv_dup(); /* duplicate value */ |
| 3038 | | − else |
| 3039 | | − vdup(); /* duplicate value */ |
| 3026 | + gv_dup(); /* duplicate value */ |
| 3040 | 3027 | vrotb(3); |
| 3041 | 3028 | vrotb(3); |
| 3042 | 3029 | } |
| @@ -4189,7 +4176,7 @@ ST_FUNC void indir(void) · 1146 unmodified lines |
| 4189 | 4176 | return; |
| 4190 | 4177 | expect("pointer"); |
| 4191 | 4178 | } |
| 4192 | | − if ((vtop->r & VT_LVAL) && !nocode_wanted) |
| 4179 | + if (vtop->r & VT_LVAL) |
| 4193 | 4180 | gv(RC_INT); |
| 4194 | 4181 | vtop->type = *pointed_type(&vtop->type); |
| 4195 | 4182 | /* Arrays and functions are never lvalues */ |
| @@ -4382,8 +4369,7 @@ ST_FUNC void unary(void) · 186 unmodified lines |
| 4382 | 4369 | if (const_wanted) |
| 4383 | 4370 | tcc_error("expected constant"); |
| 4384 | 4371 | /* save all registers */ |
| 4385 | | − if (!nocode_wanted) |
| 4386 | | − save_regs(0); |
| 4372 | + save_regs(0); |
| 4387 | 4373 | /* statement expression : we do not accept break/continue |
| 4388 | 4374 | inside as GCC does */ |
| 4389 | 4375 | block(NULL, NULL, 1); |
| @@ -4610,8 +4596,6 @@ ST_FUNC void unary(void) · 220 unmodified lines |
| 4610 | 4596 | |
| 4611 | 4597 | #ifdef TCC_TARGET_ARM64 |
| 4612 | 4598 | case TOK___va_start: { |
| 4613 | | − if (nocode_wanted) |
| 4614 | | − tcc_error("statement in global scope"); |
| 4615 | 4599 | next(); |
| 4616 | 4600 | skip('('); |
| 4617 | 4601 | expr_eq(); |
| @@ -4626,8 +4610,6 @@ ST_FUNC void unary(void) · 8 unmodified lines |
| 4626 | 4610 | } |
| 4627 | 4611 | case TOK___va_arg: { |
| 4628 | 4612 | CType type; |
| 4629 | | − if (nocode_wanted) |
| 4630 | | − tcc_error("statement in global scope"); |
| 4631 | 4613 | next(); |
| 4632 | 4614 | skip('('); |
| 4633 | 4615 | expr_eq(); |
| @@ -4906,11 +4888,7 @@ ST_FUNC void unary(void) · 272 unmodified lines |
| 4906 | 4888 | if (sa) |
| 4907 | 4889 | tcc_error("too few arguments to function"); |
| 4908 | 4890 | skip(')'); |
| 4909 | | − if (!nocode_wanted) { |
| 4910 | | − gfunc_call(nb_args); |
| 4911 | | − } else { |
| 4912 | | − vtop -= (nb_args + 1); |
| 4913 | | − } |
| 4891 | + gfunc_call(nb_args); |
| 4914 | 4892 | |
| 4915 | 4893 | /* return value */ |
| 4916 | 4894 | for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) { |
| @@ -5083,9 +5061,9 @@ static void expr_land(void) · 166 unmodified lines |
| 5083 | 5061 | expr_or(); |
| 5084 | 5062 | vpop(); |
| 5085 | 5063 | } |
| 5064 | + nocode_wanted = saved_nocode_wanted; |
| 5086 | 5065 | if (t) |
| 5087 | 5066 | gsym(t); |
| 5088 | | − nocode_wanted = saved_nocode_wanted; |
| 5089 | 5067 | gen_cast(&int_type); |
| 5090 | 5068 | break; |
| 5091 | 5069 | } |
| @@ -5127,9 +5105,9 @@ static void expr_lor(void) · 35 unmodified lines |
| 5127 | 5105 | expr_land(); |
| 5128 | 5106 | vpop(); |
| 5129 | 5107 | } |
| 5108 | + nocode_wanted = saved_nocode_wanted; |
| 5130 | 5109 | if (t) |
| 5131 | 5110 | gsym(t); |
| 5132 | | − nocode_wanted = saved_nocode_wanted; |
| 5133 | 5111 | gen_cast(&int_type); |
| 5134 | 5112 | break; |
| 5135 | 5113 | } |
| @@ -5206,16 +5184,6 @@ static void expr_cond(void) · 70 unmodified lines |
| 5206 | 5184 | } |
| 5207 | 5185 | } |
| 5208 | 5186 | else { |
| 5209 | | − /* XXX This doesn't handle nocode_wanted correctly at all. |
| 5210 | | − It unconditionally calls gv/gvtst and friends. That's |
| 5211 | | − the case for many of the expr_ routines. Currently |
| 5212 | | − that should generate only useless code, but depending |
| 5213 | | − on other operand handling this might also generate |
| 5214 | | − pointer derefs for lvalue conversions whose result |
| 5215 | | − is useless, but nevertheless can lead to segfault. |
| 5216 | | − |
| 5217 | | − Somewhen we need to overhaul the whole nocode_wanted |
| 5218 | | − handling. */ |
| 5219 | 5187 | if (vtop != vstack) { |
| 5220 | 5188 | /* needed to avoid having different registers saved in |
| 5221 | 5189 | each branch */ |
| @@ -5575,19 +5543,22 @@ static void block(int *bsym, int *csym, int is_expr) · 353 unmodified lines |
| 5575 | 5543 | gexpr(); |
| 5576 | 5544 | skip(')'); |
| 5577 | 5545 | cond = condition_3way(); |
| 5578 | | − if (cond == 0) |
| 5546 | + if (cond == 1) |
| 5547 | + a = 0, vpop(); |
| 5548 | + else |
| 5549 | + a = gvtst(1, 0); |
| 5550 | + if (cond == 0) |
| 5579 | 5551 | nocode_wanted |= 2; |
| 5580 | | − a = gvtst(1, 0); |
| 5581 | 5552 | block(bsym, csym, 0); |
| 5582 | 5553 | if (cond != 1) |
| 5583 | 5554 | nocode_wanted = saved_nocode_wanted; |
| 5584 | 5555 | c = tok; |
| 5585 | 5556 | if (c == TOK_ELSE) { |
| 5586 | 5557 | next(); |
| 5587 | | − if (cond == 1) |
| 5588 | | − nocode_wanted |= 2; |
| 5589 | 5558 | d = gjmp(0); |
| 5590 | 5559 | gsym(a); |
| 5560 | + if (cond == 1) |
| 5561 | + nocode_wanted |= 2; |
| 5591 | 5562 | block(bsym, csym, 0); |
| 5592 | 5563 | gsym(d); /* patch else jmp */ |
| 5593 | 5564 | if (cond != 0) |
| @@ -5610,8 +5581,7 @@ static void block(int *bsym, int *csym, int is_expr) · 16 unmodified lines |
| 5610 | 5581 | block(&a, &b, 0); |
| 5611 | 5582 | nocode_wanted = saved_nocode_wanted; |
| 5612 | 5583 | --local_scope; |
| 5613 | | − if(!nocode_wanted) |
| 5614 | | − gjmp_addr(d); |
| 5584 | + gjmp_addr(d); |
| 5615 | 5585 | gsym(a); |
| 5616 | 5586 | gsym_addr(b, d); |
| 5617 | 5587 | } else if (tok == '{') { |
| @@ -5801,8 +5771,7 @@ static void block(int *bsym, int *csym, int is_expr) · 183 unmodified lines |
| 5801 | 5771 | saved_nocode_wanted = nocode_wanted; |
| 5802 | 5772 | block(&a, &b, 0); |
| 5803 | 5773 | nocode_wanted = saved_nocode_wanted; |
| 5804 | | − if(!nocode_wanted) |
| 5805 | | − gjmp_addr(c); |
| 5774 | + gjmp_addr(c); |
| 5806 | 5775 | gsym(a); |
| 5807 | 5776 | gsym_addr(b, c); |
| 5808 | 5777 | --local_scope; |
| @@ -5823,11 +5792,8 @@ static void block(int *bsym, int *csym, int is_expr) · 14 unmodified lines |
| 5823 | 5792 | skip('('); |
| 5824 | 5793 | gsym(b); |
| 5825 | 5794 | gexpr(); |
| 5826 | | − if (!nocode_wanted) { |
| 5827 | | − c = gvtst(0, 0); |
| 5828 | | − gsym_addr(c, d); |
| 5829 | | − } else |
| 5830 | | − vtop--; |
| 5795 | + c = gvtst(0, 0); |
| 5796 | + gsym_addr(c, d); |
| 5831 | 5797 | nocode_wanted = saved_nocode_wanted; |
| 5832 | 5798 | skip(')'); |
| 5833 | 5799 | gsym(a); |
| @@ -5852,21 +5818,19 @@ static void block(int *bsym, int *csym, int is_expr) · 18 unmodified lines |
| 5852 | 5818 | a = gjmp(a); /* add implicit break */ |
| 5853 | 5819 | /* case lookup */ |
| 5854 | 5820 | gsym(b); |
| 5855 | | − if (!nocode_wanted) { |
| 5856 | | − qsort(sw.p, sw.n, sizeof(void*), case_cmp); |
| 5857 | | − for (b = 1; b < sw.n; b++) |
| 5858 | | − if (sw.p[b - 1]->v2 >= sw.p[b]->v1) |
| 5859 | | − tcc_error("duplicate case value"); |
| 5860 | | − /* Our switch table sorting is signed, so the compared |
| 5861 | | − value needs to be as well when it's 64bit. */ |
| 5862 | | − if ((switchval.type.t & VT_BTYPE) == VT_LLONG) |
| 5863 | | − switchval.type.t &= ~VT_UNSIGNED; |
| 5864 | | − vpushv(&switchval); |
| 5865 | | − gcase(sw.p, sw.n, &a); |
| 5866 | | − vpop(); |
| 5867 | | − if (sw.def_sym) |
| 5868 | | − gjmp_addr(sw.def_sym); |
| 5869 | | − } |
| 5821 | + qsort(sw.p, sw.n, sizeof(void*), case_cmp); |
| 5822 | + for (b = 1; b < sw.n; b++) |
| 5823 | + if (sw.p[b - 1]->v2 >= sw.p[b]->v1) |
| 5824 | + tcc_error("duplicate case value"); |
| 5825 | + /* Our switch table sorting is signed, so the compared |
| 5826 | + value needs to be as well when it's 64bit. */ |
| 5827 | + if ((switchval.type.t & VT_BTYPE) == VT_LLONG) |
| 5828 | + switchval.type.t &= ~VT_UNSIGNED; |
| 5829 | + vpushv(&switchval); |
| 5830 | + gcase(sw.p, sw.n, &a); |
| 5831 | + vpop(); |
| 5832 | + if (sw.def_sym) |
| 5833 | + gjmp_addr(sw.def_sym); |
| 5870 | 5834 | dynarray_reset(&sw.p, &sw.n); |
| 5871 | 5835 | cur_switch = saved; |
| 5872 | 5836 | /* break label */ |
| @@ -5910,10 +5874,7 @@ static void block(int *bsym, int *csym, int is_expr) · 37 unmodified lines |
| 5910 | 5874 | gexpr(); |
| 5911 | 5875 | if ((vtop->type.t & VT_BTYPE) != VT_PTR) |
| 5912 | 5876 | expect("pointer"); |
| 5913 | | − if (!nocode_wanted) |
| 5914 | | − ggoto(); |
| 5915 | | − else |
| 5916 | | − vtop--; |
| 5877 | + ggoto(); |
| 5917 | 5878 | } else if (tok >= TOK_UIDENT) { |
| 5918 | 5879 | s = label_find(tok); |
| 5919 | 5880 | /* put forward definition if needed */ |
| @@ -5924,9 +5885,7 @@ static void block(int *bsym, int *csym, int is_expr) · 4 unmodified lines |
| 5924 | 5885 | s->r = LABEL_FORWARD; |
| 5925 | 5886 | } |
| 5926 | 5887 | vla_sp_restore_root(); |
| 5927 | | − if (nocode_wanted) |
| 5928 | | − ; |
| 5929 | | − else if (s->r & LABEL_FORWARD) |
| 5888 | + if (s->r & LABEL_FORWARD) |
| 5930 | 5889 | s->jnext = gjmp(s->jnext); |
| 5931 | 5890 | else |
| 5932 | 5891 | gjmp_addr(s->jnext); |
| @@ -6893,6 +6852,7 @@ static void gen_function(Sym *sym) · 960 unmodified lines |
| 6893 | 6852 | |
| 6894 | 6853 | rsym = 0; |
| 6895 | 6854 | block(NULL, NULL, 0); |
| 6855 | + nocode_wanted = 0; |
| 6896 | 6856 | gsym(rsym); |
| 6897 | 6857 | gfunc_epilog(); |
| 6898 | 6858 | cur_text_section->data_offset = ind; |