History

nocode, noreturn

A more automatic approach to code suppression (aka. nocode_wanted) The simple rules are: - Clear 'nocode_wanted' at (im/explicit) label IF it was used - Set 'nocode_wanted' after unconditional jumps Also in order to test this then I did add the "function might return no value" warning, and then to make that work again I did add the __attribute__((noreturn)). Also moved the look ahead label check into the type parser to gain a little speed.

grischka committed 7 years ago

Commit 1b575601 parent 856904815 files · +263 −325Browse files

Unified · Split

15 files
  1. arm-gen.c +0 −5
  2. arm64-gen.c +0 −6
  3. c67-gen.c +0 −5
  4. i386-gen.c +0 −5
  5. lib/va_list.c +1 −0
  6. tcc.h +2 −0
  7. tccasm.c +0 −4
  8. tccgen.c +248 −291
  9. tccpp.c +3 −0
  10. tests/boundtest.c +2 −0
  11. tests/tcctest.c +3 −1
  12. tests/tests2/88_codeopt.c +1 −0
  13. tests/tests2/92_enum_bitfield.c +1 −0
  14. win32/include/_mingw.h +2 −2
  15. x86_64-gen.c +0 −6
arm-gen.c+0−5
@@ -382,11 +382,6 @@ void gsym_addr(int t, int a) · 381 unmodified lines
382382 }
383383 }
384384
385−void gsym(int t)
386−{
387− gsym_addr(t, ind);
388−}
389−
390385 #ifdef TCC_ARM_VFP
391386 static uint32_t vfpr(int r)
392387 {
arm64-gen.c+0−6
@@ -236,12 +236,6 @@ ST_FUNC void gsym_addr(int t_, int a_) · 235 unmodified lines
236236 }
237237 }
238238
239−// Patch all branches in list pointed to by t to branch to current location:
240−ST_FUNC void gsym(int t)
241−{
242− gsym_addr(t, ind);
243−}
244−
245239 static int arm64_type_size(int t)
246240 {
247241 switch (t & VT_BTYPE) {
c67-gen.c+0−5
@@ -226,11 +226,6 @@ void gsym_addr(int t, int a) · 225 unmodified lines
226226 }
227227 }
228228
229−void gsym(int t)
230−{
231− gsym_addr(t, ind);
232−}
233−
234229 // these are regs that tcc doesn't really know about,
235230 // but assign them unique values so the mapping routines
236231 // can distinguish them
i386-gen.c+0−5
@@ -140,11 +140,6 @@ ST_FUNC void gsym_addr(int t, int a) · 139 unmodified lines
140140 }
141141 }
142142
143−ST_FUNC void gsym(int t)
144−{
145− gsym_addr(t, ind);
146−}
147−
148143 /* instruction + 4 bytes data. Return the address of the data */
149144 static int oad(int c, int s)
150145 {
lib/va_list.c+1−0
@@ -60,6 +60,7 @@ void *__va_arg(__va_list_struct *ap, · 59 unmodified lines
6060
6161 default: /* should never happen */
6262 abort();
63+ return 0;
6364 }
6465 }
6566 #endif
tcc.h+2−0
@@ -453,6 +453,8 @@ struct FuncAttr { · 452 unmodified lines
453453 unsigned
454454 func_call : 3, /* calling convention (0..5), see below */
455455 func_type : 2, /* FUNC_OLD/NEW/ELLIPSIS */
456+ func_noreturn : 1, /* attribute((noreturn)) */
457+ xxxx : 2,
456458 func_args : 8; /* PE __stdcall args */
457459 };
458460
tccasm.c+0−4
@@ -912,9 +912,6 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 911 unmodified lines
912912 next();
913913 if (tok == TOK_EOF)
914914 break;
915− /* generate line number info */
916− if (global && s1->do_debug)
917− tcc_debug_line(s1);
918915 parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
919916 redo:
920917 if (tok == '#') {
@@ -1148,7 +1145,6 @@ ST_FUNC void asm_instr(void) · 227 unmodified lines
11481145 uint8_t clobber_regs[NB_ASM_REGS];
11491146 Section *sec;
11501147
1151− next();
11521148 /* since we always generate the asm() instruction, we can ignore
11531149 volatile */
11541150 if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
tccgen.c+248−291
@@ -44,6 +44,7 @@ static int ncleanups; · 43 unmodified lines
4444
4545 static int local_scope;
4646 static int in_sizeof;
47+static int in_generic;
4748 static int section_sym;
4849
4950 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
5657 ST_DATA int nocode_wanted; /* no code generation wanted */
5758 #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
5859 #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+
5978 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
6079 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
6180 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
@@ -3544,8 +3563,7 @@ redo: · 3482 unmodified lines
35443563 break;
35453564 case TOK_NORETURN1:
35463565 case TOK_NORETURN2:
3547− /* currently, no need to handle it because tcc does not
3548− track unused objects */
3566+ ad->f.func_noreturn = 1;
35493567 break;
35503568 case TOK_CDECL1:
35513569 case TOK_CDECL2:
@@ -4129,7 +4147,7 @@ static void parse_btype_qualify(CType *type, int qualifiers) · 577 unmodified lines
41294147 */
41304148 static int parse_btype(CType *type, AttributeDef *ad)
41314149 {
4132− int t, u, bt, st, type_found, typespec_found, g;
4150+ int t, u, bt, st, type_found, typespec_found, g, n;
41334151 Sym *s;
41344152 CType type1;
41354153
@@ -4336,6 +4354,14 @@ static int parse_btype(CType *type, AttributeDef *ad) · 200 unmodified lines
43364354 s = sym_find(tok);
43374355 if (!s || !(s->type.t & VT_TYPEDEF))
43384356 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+
43394365 t &= ~(VT_BTYPE|VT_LONG);
43404366 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
43414367 type->t = (s->type.t & ~VT_TYPEDEF) | u;
@@ -4345,7 +4371,6 @@ static int parse_btype(CType *type, AttributeDef *ad) · 3 unmodified lines
43454371 t = type->t;
43464372 /* get attributes from typedef */
43474373 sym_to_attr(ad, s);
4348− next();
43494374 typespec_found = 1;
43504375 st = bt = -2;
43514376 break;
@@ -5237,7 +5262,11 @@ ST_FUNC void unary(void) · 885 unmodified lines
52375262 AttributeDef ad_tmp;
52385263 int itmp;
52395264 CType cur_type;
5265+
5266+ in_generic++;
52405267 parse_btype(&cur_type, &ad_tmp);
5268+ in_generic--;
5269+
52415270 type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
52425271 if (compare_types(&controlling_type, &cur_type, 0)) {
52435272 if (has_match) {
@@ -5501,6 +5530,8 @@ special_math_val: · 257 unmodified lines
55015530 }
55025531 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
55035532 }
5533+ if (s->f.func_noreturn)
5534+ CODE_OFF();
55045535 } else {
55055536 break;
55065537 }
@@ -5603,86 +5634,50 @@ static void expr_or(void) · 96 unmodified lines
56035634 }
56045635 }
56055636
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+
56065669 static void expr_land(void)
56075670 {
56085671 expr_or();
5609− if (tok == TOK_LAND) {
5610− int t = 0;
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− }
5672+ if (tok == TOK_LAND)
5673+ expr_landor(expr_or, TOK_LAND, 1);
56455674 }
56465675
56475676 static void expr_lor(void)
56485677 {
56495678 expr_land();
5650− if (tok == TOK_LOR) {
5651− int t = 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− }
5679+ if (tok == TOK_LOR)
5680+ expr_landor(expr_land, TOK_LOR, 0);
56865681 }
56875682
56885683 /* Assuming vtop is a value used in a conditional context
@@ -5706,15 +5701,25 @@ static void expr_cond(void) · 17 unmodified lines
57065701 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
57075702 SValue sv;
57085703 CType type, type1, type2;
5704+ int ncw_prev;
57095705
57105706 expr_lor();
57115707 if (tok == '?') {
57125708 next();
57135709 c = condition_3way();
57145710 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) {
57165720 /* needed to avoid having different registers saved in
57175721 each branch */
5722+ rc = RC_INT;
57185723 if (is_float(vtop->type.t)) {
57195724 rc = RC_FLOAT;
57205725 #ifdef TCC_TARGET_X86_64
@@ -5722,20 +5727,14 @@ static void expr_cond(void) · 1 unmodified line
57225727 rc = RC_ST0;
57235728 }
57245729 #endif
5725− } else
5726− rc = RC_INT;
5730+ }
57275731 gv(rc);
57285732 save_regs(1);
5729− if (g)
5730− gv_dup();
5731− tt = gvtst(1, 0);
5732−
5733− } else {
5734− if (!g)
5735− vpop();
5736− tt = 0;
5733+ gv_dup();
5734+ tt = gvtst(0, 0);
57375735 }
57385736
5737+ ncw_prev = nocode_wanted;
57395738 if (1) {
57405739 if (c == 0)
57415740 nocode_wanted++;
@@ -5747,20 +5746,21 @@ static void expr_cond(void) · 5 unmodified lines
57475746 type1 = vtop->type;
57485747 sv = *vtop; /* save value to handle it later */
57495748 vtop--; /* no vpop so that FP stack is not flushed */
5750− skip(':');
57515749
5752− u = 0;
5753− if (c < 0)
5750+ if (g) {
5751+ u = tt;
5752+ } else if (c < 0) {
57545753 u = gjmp(0);
5755− gsym(tt);
5754+ gsym(tt);
5755+ } else
5756+ u = 0;
57565757
5757− if (c == 0)
5758− nocode_wanted--;
5758+ nocode_wanted = ncw_prev;
57595759 if (c == 1)
57605760 nocode_wanted++;
5761+ skip(':');
57615762 expr_cond();
5762− if (c == 1)
5763− nocode_wanted--;
5763+
57645764
57655765 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
57665766 mk_pointer(&vtop->type);
@@ -5771,7 +5771,6 @@ static void expr_cond(void) · 4 unmodified lines
57715771 bt2 = t2 & VT_BTYPE;
57725772 type.ref = NULL;
57735773
5774−
57755774 /* cast operands to correct type according to ISOC rules */
57765775 if (bt1 == VT_VOID || bt2 == VT_VOID) {
57775776 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
59025901 gaddrof();
59035902 }
59045903
5905− if (c < 0 || islv) {
5904+ if (c < 0) {
59065905 r1 = gv(rc);
59075906 move_reg(r2, r1, type.t);
59085907 vtop->r = r2;
59095908 gsym(tt);
5910− if (islv)
5911− indir();
59125909 }
5910+
5911+ if (islv)
5912+ indir();
59135913 }
5914+ nocode_wanted = ncw_prev;
59145915 }
59155916 }
59165917
@@ -5982,25 +5983,8 @@ ST_FUNC int expr_const(void) · 65 unmodified lines
59825983 return c;
59835984 }
59845985
5985−/* return the label token if current token is a label, otherwise
5986− return zero */
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−}
5986+/* ------------------------------------------------------------------------- */
5987+/* return from function */
60045988
60055989 #ifndef TCC_TARGET_ARM64
60065990 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
61356119 }
61366120 }
61376121
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+
61386166 static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr)
61396167 {
6140− int a, b, c, d, cond;
6168+ int a, b, c, d, e, t;
61416169 Sym *s;
61426170
6143− /* generate line number info */
6144− if (tcc_state->do_debug)
6145− tcc_debug_line(tcc_state);
6146−
61476171 if (is_expr) {
61486172 /* default return value is (void) */
61496173 vpushi(0);
61506174 vtop->type.t = VT_VOID;
61516175 }
61526176
6153− if (tok == TOK_IF) {
6154− /* if test */
6155− int saved_nocode_wanted = nocode_wanted;
6156− next();
6177+ t = tok, next();
6178+
6179+ if (t == TOK_IF) {
61576180 skip('(');
61586181 gexpr();
61596182 skip(')');
6160− cond = condition_3way();
6161− if (cond == 1)
6162− a = 0, vpop();
6163− else
6164− a = gvtst(1, 0);
6165− if (cond == 0)
6166− nocode_wanted |= 0x20000000;
6183+ a = gvtst(1, 0);
61676184 block(bsym, bcl, csym, ccl, 0);
6168− if (cond != 1)
6169− nocode_wanted = saved_nocode_wanted;
61706185 if (tok == TOK_ELSE) {
6171− next();
61726186 d = gjmp(0);
61736187 gsym(a);
6174− if (cond == 1)
6175− nocode_wanted |= 0x20000000;
6188+ next();
61766189 block(bsym, bcl, csym, ccl, 0);
61776190 gsym(d); /* patch else jmp */
6178− if (cond != 0)
6179− nocode_wanted = saved_nocode_wanted;
6180− } else
6191+ } else {
61816192 gsym(a);
6182− } else if (tok == TOK_WHILE) {
6183− int saved_nocode_wanted;
6184− nocode_wanted &= ~0x20000000;
6185− next();
6186− d = ind;
6193+ }
6194+
6195+ } else if (t == TOK_WHILE) {
6196+ d = gind();
61876197 vla_sp_restore();
61886198 skip('(');
61896199 gexpr();
61906200 skip(')');
61916201 a = gvtst(1, 0);
61926202 b = 0;
6193− ++local_scope;
6194− saved_nocode_wanted = nocode_wanted;
61956203 block(&a, current_cleanups, &b, current_cleanups, 0);
6196− nocode_wanted = saved_nocode_wanted;
6197− --local_scope;
61986204 gjmp_addr(d);
6199− gsym(a);
62006205 gsym_addr(b, d);
6201− } else if (tok == '{') {
6206+ gsym(a);
6207+
6208+ } else if (t == '{') {
62026209 Sym *llabel, *lcleanup;
62036210 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
62046211 int lncleanups = ncleanups;
62056212
6206− next();
62076213 /* record local declaration stack position */
62086214 s = local_stack;
62096215 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
62126218
62136219 /* handle local labels declarations */
62146220 while (tok == TOK_LABEL) {
6215− next();
6216− for(;;) {
6221+ do {
6222+ next();
62176223 if (tok < TOK_UIDENT)
62186224 expect("label identifier");
62196225 label_push(&local_label_stack, tok, LABEL_DECLARED);
62206226 next();
6221− if (tok == ',') {
6222− next();
6223− } else {
6224− skip(';');
6225− break;
6226− }
6227− }
6227+ } while (tok == ',');
6228+ skip(';');
62286229 }
6230+
62296231 while (tok != '}') {
6230− if ((a = is_label()))
6231− unget_tok(a);
6232− else
6233− decl(VT_LOCAL);
6232+ decl(VT_LOCAL);
62346233 if (tok != '}') {
62356234 if (is_expr)
62366235 vpop();
@@ -6238,39 +6237,12 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line
62386237 }
62396238 }
62406239
6241− if (current_cleanups != lcleanup) {
6242− int jmp = 0;
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− }
6240+ if (current_cleanups != lcleanup)
6241+ block_cleanup(lcleanup, lncleanups);
62676242
6268− current_cleanups = lcleanup;
6269− ncleanups = lncleanups;
62706243 /* pop locally defined labels */
62716244 label_pop(&local_label_stack, llabel, is_expr);
6272− /* pop locally defined symbols */
6273− --local_scope;
6245+
62746246 /* In the is_expr case (a statement expression is finished here),
62756247 vtop might refer to symbols on the local_stack. Either via the
62766248 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
62786250 any symbols in that case; some upper level call to block() will
62796251 do that. We do have to remove such symbols from the lookup
62806252 tables, though. sym_pop will do that. */
6253+
6254+ /* pop locally defined symbols */
62816255 sym_pop(&local_stack, s, is_expr);
62826256
62836257 /* 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
62876261 }
62886262 vlas_in_scope = saved_vlas_in_scope;
62896263
6264+ if (0 == --local_scope && !nocode_wanted)
6265+ check_func_return();
62906266 next();
6291− } else if (tok == TOK_RETURN) {
6292− next();
6293− if (tok != ';') {
6294− gexpr();
6295− gen_assign_cast(&func_vt);
6296− try_call_scope_cleanup(NULL);
6297− if ((func_vt.t & VT_BTYPE) == VT_VOID)
6298− vtop--;
6299− else
6300− gfunc_return(&func_vt);
6301− } else {
6302− try_call_scope_cleanup(NULL);
6303− }
6267+
6268+ } else if (t == TOK_RETURN) {
6269+ a = tok != ';';
6270+ b = (func_vt.t & VT_BTYPE) != VT_VOID;
6271+ if (a)
6272+ gexpr(), gen_assign_cast(&func_vt);
6273+ try_call_scope_cleanup(NULL);
6274+ if (a && b)
6275+ gfunc_return(&func_vt);
6276+ else if (a)
6277+ vtop--;
6278+ else if (b)
6279+ tcc_warning("'return' with no value.");
63046280 skip(';');
63056281 /* jump unless last stmt in top-level block */
63066282 if (tok != '}' || local_scope != 1)
63076283 rsym = gjmp(rsym);
6308− nocode_wanted |= 0x20000000;
6309− } else if (tok == TOK_BREAK) {
6284+ CODE_OFF();
6285+
6286+ } else if (t == TOK_BREAK) {
63106287 /* compute jump */
63116288 if (!bsym)
63126289 tcc_error("cannot break");
63136290 try_call_scope_cleanup(bcl);
63146291 *bsym = gjmp(*bsym);
6315− next();
63166292 skip(';');
6317− nocode_wanted |= 0x20000000;
6318− } else if (tok == TOK_CONTINUE) {
6293+
6294+ } else if (t == TOK_CONTINUE) {
63196295 /* compute jump */
63206296 if (!csym)
63216297 tcc_error("cannot continue");
63226298 try_call_scope_cleanup(ccl);
63236299 vla_sp_restore_root();
63246300 *csym = gjmp(*csym);
6325− next();
63266301 skip(';');
6327− nocode_wanted |= 0x20000000;
6328− } else if (tok == TOK_FOR) {
6329− int e;
6330− int saved_nocode_wanted;
6302+
6303+ } else if (t == TOK_FOR) {
63316304 Sym *lcleanup = current_cleanups;
63326305 int lncleanups = ncleanups;
63336306
6334− nocode_wanted &= ~0x20000000;
6335− next();
63366307 skip('(');
63376308 s = local_stack;
63386309 ++local_scope;
@@ -6345,11 +6316,9 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 6 unmodified lines
63456316 }
63466317 }
63476318 skip(';');
6348− d = ind;
6349− c = ind;
6319+ a = b = 0;
6320+ c = d = gind();
63506321 vla_sp_restore();
6351− a = 0;
6352− b = 0;
63536322 if (tok != ';') {
63546323 gexpr();
63556324 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
63576326 skip(';');
63586327 if (tok != ')') {
63596328 e = gjmp(0);
6360− c = ind;
6329+ d = gind();
63616330 vla_sp_restore();
63626331 gexpr();
63636332 vpop();
6364− gjmp_addr(d);
6333+ gjmp_addr(c);
63656334 gsym(e);
63666335 }
63676336 skip(')');
6368− saved_nocode_wanted = nocode_wanted;
63696337 block(&a, current_cleanups, &b, current_cleanups, 0);
6370− nocode_wanted = saved_nocode_wanted;
6371− gjmp_addr(c);
6338+ gjmp_addr(d);
6339+ gsym_addr(b, d);
63726340 gsym(a);
6373− gsym_addr(b, c);
63746341 --local_scope;
63756342 try_call_scope_cleanup(lcleanup);
63766343 ncleanups = lncleanups;
63776344 current_cleanups = lcleanup;
63786345 sym_pop(&local_stack, s, 0);
63796346
6380− } else
6381− if (tok == TOK_DO) {
6382− int saved_nocode_wanted;
6383− nocode_wanted &= ~0x20000000;
6384− next();
6385− a = 0;
6386− b = 0;
6387− d = ind;
6347+ } else if (t == TOK_DO) {
6348+ a = b = 0;
6349+ d = gind();
63886350 vla_sp_restore();
6389− saved_nocode_wanted = nocode_wanted;
63906351 block(&a, current_cleanups, &b, current_cleanups, 0);
6352+ gsym(b);
63916353 skip(TOK_WHILE);
63926354 skip('(');
6393− gsym(b);
6394− if (b)
6395− nocode_wanted = saved_nocode_wanted;
63966355 gexpr();
6356+ skip(')');
6357+ skip(';');
63976358 c = gvtst(0, 0);
63986359 gsym_addr(c, d);
6399− nocode_wanted = saved_nocode_wanted;
6400− skip(')');
64016360 gsym(a);
6402− skip(';');
6403− } else
6404− if (tok == TOK_SWITCH) {
6361+
6362+ } else if (t == TOK_SWITCH) {
64056363 struct switch_t *saved, sw;
6406− int saved_nocode_wanted = nocode_wanted;
64076364 SValue switchval;
6408− next();
6365+
64096366 skip('(');
64106367 gexpr();
64116368 skip(')');
@@ -6416,7 +6373,6 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 4 unmodified lines
64166373 saved = cur_switch;
64176374 cur_switch = &sw;
64186375 block(&a, current_cleanups, csym, ccl, 0);
6419− nocode_wanted = saved_nocode_wanted;
64206376 a = gjmp(a); /* add implicit break */
64216377 /* case lookup */
64226378 gsym(b);
@@ -6437,13 +6393,11 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 14 unmodified lines
64376393 cur_switch = saved;
64386394 /* break label */
64396395 gsym(a);
6440− } else
6441− if (tok == TOK_CASE) {
6396+
6397+ } else if (t == TOK_CASE) {
64426398 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
64436399 if (!cur_switch)
64446400 expect("switch");
6445− nocode_wanted &= ~0x20000000;
6446− next();
64476401 cr->v1 = cr->v2 = expr_const64();
64486402 if (gnu_ext && tok == TOK_DOTS) {
64496403 next();
@@ -6451,25 +6405,23 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line
64516405 if (cr->v2 < cr->v1)
64526406 tcc_warning("empty case range");
64536407 }
6454− cr->sym = ind;
6408+ cr->sym = gind();
64556409 dynarray_add(&cur_switch->p, &cur_switch->n, cr);
64566410 skip(':');
64576411 is_expr = 0;
64586412 goto block_after_label;
6459− } else
6460− if (tok == TOK_DEFAULT) {
6461− next();
6462− skip(':');
6413+
6414+ } else if (t == TOK_DEFAULT) {
64636415 if (!cur_switch)
64646416 expect("switch");
64656417 if (cur_switch->def_sym)
64666418 tcc_error("too many 'default'");
6467− cur_switch->def_sym = ind;
6419+ cur_switch->def_sym = gind();
6420+ skip(':');
64686421 is_expr = 0;
64696422 goto block_after_label;
6470− } else
6471− if (tok == TOK_GOTO) {
6472− next();
6423+
6424+ } else if (t == TOK_GOTO) {
64736425 if (tok == '*' && gnu_ext) {
64746426 /* computed goto */
64756427 next();
@@ -6500,18 +6452,20 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 24 unmodified lines
65006452 gjmp_addr(s->jnext);
65016453 }
65026454 next();
6503− } else {
6455+
6456+ } else {
65046457 expect("label identifier");
65056458 }
65066459 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) {
65086462 asm_instr();
6463+
65096464 } else {
6510− b = is_label();
6511− if (b) {
6465+ if (tok == ':' && t >= TOK_UIDENT) {
65126466 /* label case */
65136467 next();
6514− s = label_find(b);
6468+ s = label_find(t);
65156469 if (s) {
65166470 if (s->r == LABEL_DEFINED)
65176471 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
65246478 } else
65256479 gsym(s->jnext);
65266480 } else {
6527− s = label_push(&global_label_stack, b, LABEL_DEFINED);
6481+ s = label_push(&global_label_stack, t, LABEL_DEFINED);
65286482 }
6529− s->jnext = ind;
6530− s->cleanupstate = current_cleanups;
6483+ s->jnext = gind();
6484+ s->cleanupstate = current_cleanups;
6485+
6486+ block_after_label:
65316487 vla_sp_restore();
65326488 /* we accept this, but it is a mistake */
6533− block_after_label:
6534− nocode_wanted &= ~0x20000000;
65356489 if (tok == '}') {
65366490 tcc_warning("deprecated use of label at end of compound statement");
65376491 } else {
@@ -6539,9 +6493,11 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line
65396493 vpop();
65406494 block(bsym, bcl, csym, ccl, is_expr);
65416495 }
6496+
65426497 } else {
65436498 /* expression case */
6544− if (tok != ';') {
6499+ if (t != ';') {
6500+ unget_tok(t);
65456501 if (is_expr) {
65466502 vpop();
65476503 gexpr();
@@ -6549,8 +6505,8 @@ static void block(int *bsym, Sym *bcl, int *csym, Sym *ccl, int is_expr) · 1 unmodified line
65496505 gexpr();
65506506 vpop();
65516507 }
6508+ skip(';');
65526509 }
6553− skip(';');
65546510 }
65556511 }
65566512 }
@@ -6661,10 +6617,17 @@ static int decl_designator(CType *type, Section *sec, unsigned long c, · 104 unmodified lines
66616617
66626618 elem_size = 0;
66636619 nb_elems = 1;
6620+
66646621 if (flags & DIF_HAVE_ELEM)
66656622 goto no_designator;
6666− if (gnu_ext && (l = is_label()) != 0)
6667− goto struct_field;
6623+
6624+ if (gnu_ext && tok >= TOK_UIDENT) {
6625+ l = tok, next();
6626+ if (tok == ':')
6627+ goto struct_field;
6628+ unget_tok(l);
6629+ }
6630+
66686631 /* NOTE: we only support ranges for last designator */
66696632 while (nb_elems == 1 && (tok == '[' || tok == '.')) {
66706633 if (tok == '[') {
@@ -7413,19 +7376,10 @@ static void gen_function(Sym *sym) · 742 unmodified lines
74137376 gfunc_prolog(&sym->type);
74147377 reset_local_scope();
74157378 rsym = 0;
7416− clear_temp_local_var_list();
7417− 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;
7379+ clear_temp_local_var_list();
7380+ block(NULL, NULL, NULL, NULL, 0);
74287381 gsym(rsym);
7382+ nocode_wanted = 0;
74297383 gfunc_epilog();
74307384 cur_text_section->data_offset = ind;
74317385 label_pop(&global_label_stack, NULL, 0);
@@ -7746,3 +7700,6 @@ static void decl(int l) · 314 unmodified lines
77467700 }
77477701
77487702 /* ------------------------------------------------------------------------- */
7703+#undef gjmp_addr
7704+#undef gjmp
7705+/* ------------------------------------------------------------------------- */
tccpp.c+3−0
@@ -3527,6 +3527,9 @@ no_subst: · 3526 unmodified lines
35273527 /* return next token with macro substitution */
35283528 ST_FUNC void next(void)
35293529 {
3530+ /* generate line number info */
3531+ if (tcc_state->do_debug)
3532+ tcc_debug_line(tcc_state);
35303533 redo:
35313534 if (parse_flags & PARSE_FLAG_SPACES)
35323535 next_nomacro_spc();
tests/boundtest.c+2−0
@@ -209,6 +209,7 @@ int test16() · 208 unmodified lines
209209 printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
210210
211211 fprintf(stderr, "%s end\n", __FUNCTION__);
212+ return 0;
212213 }
213214
214215 /* error */
@@ -227,6 +228,7 @@ int test17() · 12 unmodified lines
227228 printf("alloca: %s\n", strcpy(alloca(strlen(demo)),demo) );
228229
229230 fprintf(stderr, "%s end\n", __FUNCTION__);
231+ return 0;
230232 }
231233
232234 int (*table_test[])(void) = {
tests/tcctest.c+3−1
@@ -179,7 +179,7 @@ static int onetwothree = 123; · 178 unmodified lines
179179
180180 #ifdef __TINYC__
181181 /* We try to handle this syntax. Make at least sure it doesn't segfault. */
182−char invalid_function_def()[] {}
182+char invalid_function_def()[] {return 0;}
183183 #endif
184184
185185 #define __INT64_C(c) c ## LL
@@ -572,6 +572,7 @@ void goto_test() · 386 unmodified lines
572572 printf("goto:\n");
573573 i = 0;
574574 /* This needs to parse as label, not as start of decl. */
575+ typedef_and_label x;
575576 typedef_and_label:
576577 s_loop:
577578 if (i >= 10)
@@ -3767,6 +3768,7 @@ int fcompare (double a, double b, int code) · 3189 unmodified lines
37673768 case 4: return a > b;
37683769 case 5: return a <= b;
37693770 }
3771+ return 0;
37703772 }
37713773
37723774 void math_cmp_test(void)
tests/tests2/88_codeopt.c+1−0
@@ -51,6 +51,7 @@ _Bool chk(unsigned long addr, unsigned long limit, unsigned long size) · 50 unmodified lines
5151 only with certain internal checking added that's not committed). */
5252 if (0)
5353 ret = 0 != (!!(addr > limit - size));
54+ return 0;
5455 }
5556
5657 int main()
tests/tests2/92_enum_bitfield.c+1−0
@@ -45,6 +45,7 @@ int convert_like_real (tree convs) · 44 unmodified lines
4545 break;
4646 };
4747 printf("unsigned enum bit-fields broken\n");
48+ return 0;
4849 }
4950
5051 int main()
win32/include/_mingw.h+2−2
@@ -41,7 +41,7 @@ · 40 unmodified lines
4141 #define __MSVCRT__ 1
4242 #undef _MSVCRT_
4343 #define __MINGW_IMPORT extern __declspec(dllimport)
44−#define __MINGW_ATTRIB_NORETURN
44+#define __MINGW_ATTRIB_NORETURN __declspec(noreturn)
4545 #define __MINGW_ATTRIB_CONST
4646 #define __MINGW_ATTRIB_DEPRECATED
4747 #define __MINGW_ATTRIB_MALLOC
@@ -138,7 +138,7 @@ typedef struct localeinfo_struct _locale_tstruct,*_locale_t; · 90 unmodified lines
138138 /* for winapi */
139139 #define _ANONYMOUS_UNION
140140 #define _ANONYMOUS_STRUCT
141−#define DECLSPEC_NORETURN
141+#define DECLSPEC_NORETURN __declspec(noreturn)
142142 #define DECLARE_STDCALL_P(type) __stdcall type
143143 #define NOSERVICE 1
144144 #define NOMCX 1
x86_64-gen.c+0−6
@@ -211,12 +211,6 @@ ST_FUNC void gsym_addr(int t, int a) · 210 unmodified lines
211211 }
212212 }
213213
214−void gsym(int t)
215−{
216− gsym_addr(t, ind);
217−}
218−
219−
220214 static int is64_type(int t)
221215 {
222216 return ((t & VT_BTYPE) == VT_PTR ||

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t