- integrate CONST_WANTED with nocode_wanted - expr_const() checks VT_NONCONST
Unified · Split
| @@ -1421,7 +1421,6 @@ ST_DATA SValue *vtop; · 1420 unmodified lines | ||
| 1421 | 1421 | ST_DATA int rsym, anon_sym, ind, loc; |
| 1422 | 1422 | ST_DATA char debug_modes; |
| 1423 | 1423 | |
| 1424 | −ST_DATA int const_wanted; /* true if constant wanted */ | |
| 1425 | 1424 | ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ |
| 1426 | 1425 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ |
| 1427 | 1426 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ |
| @@ -51,15 +51,24 @@ ST_DATA SValue *vtop; · 50 unmodified lines | ||
| 51 | 51 | static SValue _vstack[1 + VSTACK_SIZE]; |
| 52 | 52 | #define vstack (_vstack + 1) |
| 53 | 53 | |
| 54 | −ST_DATA int const_wanted; /* true if constant wanted */ | |
| 55 | 54 | ST_DATA int nocode_wanted; /* no code generation wanted */ |
| 56 | −#define unevalmask 0xffff /* unevaluated subexpression */ | |
| 57 | 55 | #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */ |
| 58 | 56 | #define DATA_ONLY_WANTED 0x80000000 /* ON outside of functions and for static initializers */ |
| 57 | + | |
| 58 | +/* no code output after unconditional jumps such as with if (0) ... */ | |
| 59 | 59 | #define CODE_OFF_BIT 0x20000000 |
| 60 | 60 | #define CODE_OFF() if(!nocode_wanted)(nocode_wanted |= CODE_OFF_BIT) |
| 61 | 61 | #define CODE_ON() (nocode_wanted &= ~CODE_OFF_BIT) |
| 62 | 62 | |
| 63 | +/* no code output when parsing sizeof()/typeof() etc. (using nocode_wanted++/--) */ | |
| 64 | +#define NOEVAL_MASK 0x0000FFFF | |
| 65 | +#define NOEVAL_WANTED (nocode_wanted & NOEVAL_MASK) | |
| 66 | + | |
| 67 | +/* no code output when parsing constant expressions */ | |
| 68 | +#define CONST_WANTED_BIT 0x00010000 | |
| 69 | +#define CONST_WANTED_MASK 0x0FFF0000 | |
| 70 | +#define CONST_WANTED (nocode_wanted & CONST_WANTED_MASK) | |
| 71 | + | |
| 63 | 72 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ |
| 64 | 73 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ |
| 65 | 74 | ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */ |
| @@ -375,7 +384,6 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 309 unmodified lines | ||
| 375 | 384 | funcname = ""; |
| 376 | 385 | func_ind = -1; |
| 377 | 386 | anon_sym = SYM_FIRST_ANOM; |
| 378 | − const_wanted = 0; | |
| 379 | 387 | nocode_wanted = DATA_ONLY_WANTED; /* no code outside of functions */ |
| 380 | 388 | local_scope = 0; |
| 381 | 389 | debug_modes = (s1->do_debug ? 1 : 0) | s1->test_coverage << 1; |
| @@ -2274,10 +2282,10 @@ static void gen_opic(int op) · 1892 unmodified lines | ||
| 2274 | 2282 | int t2 = v2->type.t & VT_BTYPE; |
| 2275 | 2283 | int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| 2276 | 2284 | int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; |
| 2277 | − int nonconst = (v1->r | v2->r) & VT_NONCONST; | |
| 2278 | 2285 | uint64_t l1 = c1 ? v1->c.i : 0; |
| 2279 | 2286 | uint64_t l2 = c2 ? v2->c.i : 0; |
| 2280 | 2287 | int shm = (t1 == VT_LLONG) ? 63 : 31; |
| 2288 | + int r; | |
| 2281 | 2289 | |
| 2282 | 2290 | if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR)) |
| 2283 | 2291 | l1 = ((uint32_t)l1 | |
| @@ -2302,7 +2310,7 @@ static void gen_opic(int op) · 18 unmodified lines | ||
| 2302 | 2310 | case TOK_UMOD: |
| 2303 | 2311 | /* if division by zero, generate explicit division */ |
| 2304 | 2312 | if (l2 == 0) { |
| 2305 | − if (const_wanted && !(nocode_wanted & unevalmask)) | |
| 2313 | + if (CONST_WANTED && !NOEVAL_WANTED) | |
| 2306 | 2314 | tcc_error("division by zero in constant"); |
| 2307 | 2315 | goto general_case; |
| 2308 | 2316 | } |
| @@ -2339,9 +2347,9 @@ static void gen_opic(int op) · 30 unmodified lines | ||
| 2339 | 2347 | l1 = ((uint32_t)l1 | |
| 2340 | 2348 | (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000))); |
| 2341 | 2349 | v1->c.i = l1; |
| 2350 | + v1->r |= v2->r & VT_NONCONST; | |
| 2342 | 2351 | vtop--; |
| 2343 | 2352 | } else { |
| 2344 | − nonconst = VT_NONCONST; | |
| 2345 | 2353 | /* if commutative ops, put c2 as constant */ |
| 2346 | 2354 | if (c1 && (op == '+' || op == '&' || op == '^' || |
| 2347 | 2355 | op == '|' || op == '*' || op == TOK_EQ || op == TOK_NE)) { |
| @@ -2349,14 +2357,12 @@ static void gen_opic(int op) · 1 unmodified line | ||
| 2349 | 2357 | c2 = c1; //c = c1, c1 = c2, c2 = c; |
| 2350 | 2358 | l2 = l1; //l = l1, l1 = l2, l2 = l; |
| 2351 | 2359 | } |
| 2352 | − if (!const_wanted && | |
| 2353 | − c1 && ((l1 == 0 && | |
| 2360 | + if (c1 && ((l1 == 0 && | |
| 2354 | 2361 | (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) || |
| 2355 | 2362 | (l1 == -1 && op == TOK_SAR))) { |
| 2356 | 2363 | /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */ |
| 2357 | − vtop--; | |
| 2358 | − } else if (!const_wanted && | |
| 2359 | − c2 && ((l2 == 0 && (op == '&' || op == '*')) || | |
| 2364 | + vpop(); | |
| 2365 | + } else if (c2 && ((l2 == 0 && (op == '&' || op == '*')) || | |
| 2360 | 2366 | (op == '|' && |
| 2361 | 2367 | (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) || |
| 2362 | 2368 | (l2 == 1 && (op == '%' || op == TOK_UMOD)))) { |
| @@ -2393,8 +2399,8 @@ static void gen_opic(int op) · 30 unmodified lines | ||
| 2393 | 2399 | } |
| 2394 | 2400 | goto general_case; |
| 2395 | 2401 | } else if (c2 && (op == '+' || op == '-') && |
| 2396 | − (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM)) | |
| 2397 | − || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) { | |
| 2402 | + (r = vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM), | |
| 2403 | + r == (VT_CONST | VT_SYM) || r == VT_LOCAL)) { | |
| 2398 | 2404 | /* symbol + constant case */ |
| 2399 | 2405 | if (op == '-') |
| 2400 | 2406 | l2 = -l2; |
| @@ -2414,9 +2420,9 @@ static void gen_opic(int op) · 13 unmodified lines | ||
| 2414 | 2420 | else |
| 2415 | 2421 | gen_opi(op); |
| 2416 | 2422 | } |
| 2423 | + if (vtop->r == VT_CONST) | |
| 2424 | + vtop->r |= VT_NONCONST; /* is const, but only by optimization */ | |
| 2417 | 2425 | } |
| 2418 | − if (vtop->r == VT_CONST) | |
| 2419 | − vtop->r |= nonconst; | |
| 2420 | 2426 | } |
| 2421 | 2427 | |
| 2422 | 2428 | #if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386 |
| @@ -2484,7 +2490,7 @@ static void gen_opif(int op) · 61 unmodified lines | ||
| 2484 | 2490 | } |
| 2485 | 2491 | /* NOTE: we only do constant propagation if finite number (not |
| 2486 | 2492 | NaN or infinity) (ANSI spec) */ |
| 2487 | − if (!(ieee_finite(f1) || !ieee_finite(f2)) && !const_wanted) | |
| 2493 | + if (!(ieee_finite(f1) || !ieee_finite(f2)) && !CONST_WANTED) | |
| 2488 | 2494 | goto general_case; |
| 2489 | 2495 | switch(op) { |
| 2490 | 2496 | case '+': f1 += f2; break; |
| @@ -2495,7 +2501,7 @@ static void gen_opif(int op) · 4 unmodified lines | ||
| 2495 | 2501 | union { float f; unsigned u; } x1, x2, y; |
| 2496 | 2502 | /* If not in initializer we need to potentially generate |
| 2497 | 2503 | FP exceptions at runtime, otherwise we want to fold. */ |
| 2498 | − if (!const_wanted) | |
| 2504 | + if (!CONST_WANTED) | |
| 2499 | 2505 | goto general_case; |
| 2500 | 2506 | /* the run-time result of 0.0/0.0 on x87, also of other compilers |
| 2501 | 2507 | when used to compile the f1 /= f2 below, would be -nan */ |
| @@ -2965,7 +2971,7 @@ redo: · 463 unmodified lines | ||
| 2965 | 2971 | vpush_type_size(pointed_type(&vtop[-1].type), &align); |
| 2966 | 2972 | gen_op('*'); |
| 2967 | 2973 | #ifdef CONFIG_TCC_BCHECK |
| 2968 | − if (tcc_state->do_bounds_check && !const_wanted) { | |
| 2974 | + if (tcc_state->do_bounds_check && !CONST_WANTED) { | |
| 2969 | 2975 | /* if bounded pointers, we generate a special code to |
| 2970 | 2976 | test bounds */ |
| 2971 | 2977 | if (op == '-') { |
| @@ -5533,7 +5539,7 @@ ST_FUNC void unary(void) · 2561 unmodified lines | ||
| 5533 | 5539 | } |
| 5534 | 5540 | } else if (tok == '{') { |
| 5535 | 5541 | int saved_nocode_wanted = nocode_wanted; |
| 5536 | − if (const_wanted && !(nocode_wanted & unevalmask)) | |
| 5542 | + if (CONST_WANTED && !NOEVAL_WANTED) | |
| 5537 | 5543 | expect("constant"); |
| 5538 | 5544 | if (0 == local_scope) |
| 5539 | 5545 | tcc_error("statement expression outside of function"); |
| @@ -5848,17 +5854,19 @@ ST_FUNC void unary(void) · 308 unmodified lines | ||
| 5848 | 5854 | int has_match = 0; |
| 5849 | 5855 | int learn = 0; |
| 5850 | 5856 | TokenString *str = NULL; |
| 5851 | − int saved_const_wanted = const_wanted; | |
| 5857 | + int saved_nocode_wanted = nocode_wanted; | |
| 5858 | + nocode_wanted &= ~CONST_WANTED_MASK; | |
| 5852 | 5859 | |
| 5853 | − next(); | |
| 5860 | + next(); | |
| 5854 | 5861 | skip('('); |
| 5855 | − const_wanted = 0; | |
| 5856 | 5862 | expr_type(&controlling_type, expr_eq); |
| 5857 | 5863 | controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY); |
| 5858 | 5864 | if ((controlling_type.t & VT_BTYPE) == VT_FUNC) |
| 5859 | 5865 | mk_pointer(&controlling_type); |
| 5860 | − const_wanted = saved_const_wanted; | |
| 5861 | − for (;;) { | |
| 5866 | + | |
| 5867 | + nocode_wanted = saved_nocode_wanted; | |
| 5868 | + | |
| 5869 | + for (;;) { | |
| 5862 | 5870 | learn = 0; |
| 5863 | 5871 | skip(','); |
| 5864 | 5872 | if (tok == TOK_DEFAULT) { |
| @@ -6532,11 +6540,9 @@ ST_FUNC void gexpr(void) · 667 unmodified lines | ||
| 6532 | 6540 | /* parse a constant expression and return value in vtop. */ |
| 6533 | 6541 | static void expr_const1(void) |
| 6534 | 6542 | { |
| 6535 | − const_wanted++; | |
| 6536 | − nocode_wanted += unevalmask + 1; | |
| 6543 | + nocode_wanted += CONST_WANTED_BIT; | |
| 6537 | 6544 | expr_cond(); |
| 6538 | − nocode_wanted -= unevalmask + 1; | |
| 6539 | − const_wanted--; | |
| 6545 | + nocode_wanted -= CONST_WANTED_BIT; | |
| 6540 | 6546 | } |
| 6541 | 6547 | |
| 6542 | 6548 | /* parse an integer constant and return its value. */ |
| @@ -6544,7 +6550,7 @@ static inline int64_t expr_const64(void) · 1 unmodified line | ||
| 6544 | 6550 | { |
| 6545 | 6551 | int64_t c; |
| 6546 | 6552 | expr_const1(); |
| 6547 | − if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) | |
| 6553 | + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM | VT_NONCONST)) != VT_CONST) | |
| 6548 | 6554 | expect("constant expression"); |
| 6549 | 6555 | c = vtop->c.i; |
| 6550 | 6556 | vpop(); |