We didn't handle constants in logical expressions when they weren't the first operand. Some reordering in the loop structure is enough to handle them.
Unified · Split
| @@ -4909,37 +4909,43 @@ static void expr_land(void) · 4908 unmodified lines | ||
| 4909 | 4909 | { |
| 4910 | 4910 | expr_or(); |
| 4911 | 4911 | if (tok == TOK_LAND) { |
| 4912 | − if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 4913 | − CType ctb, cti; | |
| 4914 | − ctb.t = VT_BOOL; | |
| 4915 | − cti.t = VT_INT; | |
| 4916 | − next(); | |
| 4917 | − gen_cast(&ctb); | |
| 4918 | − if (vtop->c.i) { | |
| 4919 | − vpop(); | |
| 4920 | − expr_land(); | |
| 4921 | − gen_cast(&ctb); | |
| 4922 | − } else { | |
| 4923 | − int saved_nocode_wanted = nocode_wanted; | |
| 4924 | − nocode_wanted = 1; | |
| 4925 | − expr_land(); | |
| 4926 | − vpop(); | |
| 4927 | − nocode_wanted = saved_nocode_wanted; | |
| 4928 | − } | |
| 4929 | − gen_cast(&cti); | |
| 4930 | − } else { | |
| 4931 | − int t = 0; | |
| 4932 | − save_regs(1); | |
| 4933 | − for(;;) { | |
| 4934 | − t = gvtst(1, t); | |
| 4935 | − if (tok != TOK_LAND) { | |
| 4936 | − vseti(VT_JMPI, t); | |
| 4937 | − break; | |
| 4938 | − } | |
| 4939 | − next(); | |
| 4940 | − expr_or(); | |
| 4941 | − } | |
| 4942 | − } | |
| 4912 | + int t = 0; | |
| 4913 | + for(;;) { | |
| 4914 | + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 4915 | + CType ctb; | |
| 4916 | + ctb.t = VT_BOOL; | |
| 4917 | + gen_cast(&ctb); | |
| 4918 | + if (vtop->c.i) { | |
| 4919 | + vpop(); | |
| 4920 | + } else { | |
| 4921 | + int saved_nocode_wanted = nocode_wanted; | |
| 4922 | + nocode_wanted = 1; | |
| 4923 | + while (tok == TOK_LAND) { | |
| 4924 | + next(); | |
| 4925 | + expr_or(); | |
| 4926 | + vpop(); | |
| 4927 | + } | |
| 4928 | + if (t) | |
| 4929 | + gsym(t); | |
| 4930 | + nocode_wanted = saved_nocode_wanted; | |
| 4931 | + gen_cast(&int_type); | |
| 4932 | + break; | |
| 4933 | + } | |
| 4934 | + } else { | |
| 4935 | + if (!t) | |
| 4936 | + save_regs(1); | |
| 4937 | + t = gvtst(1, t); | |
| 4938 | + } | |
| 4939 | + if (tok != TOK_LAND) { | |
| 4940 | + if (t) | |
| 4941 | + vseti(VT_JMPI, t); | |
| 4942 | + else | |
| 4943 | + vpushi(1); | |
| 4944 | + break; | |
| 4945 | + } | |
| 4946 | + next(); | |
| 4947 | + expr_or(); | |
| 4948 | + } | |
| 4943 | 4949 | } |
| 4944 | 4950 | } |
| 4945 | 4951 | |
| @@ -4947,37 +4953,43 @@ static void expr_lor(void) · 1 unmodified line | ||
| 4947 | 4953 | { |
| 4948 | 4954 | expr_land(); |
| 4949 | 4955 | if (tok == TOK_LOR) { |
| 4950 | − if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 4951 | − CType ctb, cti; | |
| 4952 | − ctb.t = VT_BOOL; | |
| 4953 | − cti.t = VT_INT; | |
| 4954 | − next(); | |
| 4955 | − gen_cast(&ctb); | |
| 4956 | − if (vtop->c.i) { | |
| 4957 | − int saved_nocode_wanted = nocode_wanted; | |
| 4958 | − nocode_wanted = 1; | |
| 4959 | − expr_lor(); | |
| 4960 | − vpop(); | |
| 4961 | − nocode_wanted = saved_nocode_wanted; | |
| 4962 | − } else { | |
| 4963 | − vpop(); | |
| 4964 | − expr_lor(); | |
| 4965 | − gen_cast(&ctb); | |
| 4966 | − } | |
| 4967 | − gen_cast(&cti); | |
| 4968 | − } else { | |
| 4969 | − int t = 0; | |
| 4970 | − save_regs(1); | |
| 4971 | − for(;;) { | |
| 4972 | − t = gvtst(0, t); | |
| 4973 | − if (tok != TOK_LOR) { | |
| 4974 | − vseti(VT_JMP, t); | |
| 4975 | − break; | |
| 4976 | − } | |
| 4977 | − next(); | |
| 4978 | − expr_land(); | |
| 4979 | − } | |
| 4980 | − } | |
| 4956 | + int t = 0; | |
| 4957 | + for(;;) { | |
| 4958 | + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | |
| 4959 | + CType ctb; | |
| 4960 | + ctb.t = VT_BOOL; | |
| 4961 | + gen_cast(&ctb); | |
| 4962 | + if (!vtop->c.i) { | |
| 4963 | + vpop(); | |
| 4964 | + } else { | |
| 4965 | + int saved_nocode_wanted = nocode_wanted; | |
| 4966 | + nocode_wanted = 1; | |
| 4967 | + while (tok == TOK_LOR) { | |
| 4968 | + next(); | |
| 4969 | + expr_land(); | |
| 4970 | + vpop(); | |
| 4971 | + } | |
| 4972 | + if (t) | |
| 4973 | + gsym(t); | |
| 4974 | + nocode_wanted = saved_nocode_wanted; | |
| 4975 | + gen_cast(&int_type); | |
| 4976 | + break; | |
| 4977 | + } | |
| 4978 | + } else { | |
| 4979 | + if (!t) | |
| 4980 | + save_regs(1); | |
| 4981 | + t = gvtst(0, t); | |
| 4982 | + } | |
| 4983 | + if (tok != TOK_LOR) { | |
| 4984 | + if (t) | |
| 4985 | + vseti(VT_JMP, t); | |
| 4986 | + else | |
| 4987 | + vpushi(0); | |
| 4988 | + break; | |
| 4989 | + } | |
| 4990 | + next(); | |
| 4991 | + expr_land(); | |
| 4992 | + } | |
| 4981 | 4993 | } |
| 4982 | 4994 | } |
| 4983 | 4995 | |
| @@ -1232,6 +1232,38 @@ void optimize_out(void) · 1231 unmodified lines | ||
| 1232 | 1232 | printf("ool6:%d\n", defined_function()); |
| 1233 | 1233 | goto breakhere; |
| 1234 | 1234 | } |
| 1235 | + | |
| 1236 | + /* Test that constants in logical && are optimized: */ | |
| 1237 | + i = 0 && undefined_function(); | |
| 1238 | + i = defined_function() && 0 && undefined_function(); | |
| 1239 | + if (0 && undefined_function()) | |
| 1240 | + undefined_function(); | |
| 1241 | + if (defined_function() && 0) | |
| 1242 | + undefined_function(); | |
| 1243 | + if (0 && 0) | |
| 1244 | + undefined_function(); | |
| 1245 | + if (defined_function() && 0 && undefined_function()) | |
| 1246 | + undefined_function(); | |
| 1247 | + /* The same for || : */ | |
| 1248 | + i = 1 || undefined_function(); | |
| 1249 | + i = defined_function() || 1 || undefined_function(); | |
| 1250 | + if (1 || undefined_function()) | |
| 1251 | + ; | |
| 1252 | + else | |
| 1253 | + undefined_function(); | |
| 1254 | + if (defined_function() || 1) | |
| 1255 | + ; | |
| 1256 | + else | |
| 1257 | + undefined_function(); | |
| 1258 | + if (1 || 1) | |
| 1259 | + ; | |
| 1260 | + else | |
| 1261 | + undefined_function(); | |
| 1262 | + if (defined_function() || 1 || undefined_function()) | |
| 1263 | + ; | |
| 1264 | + else | |
| 1265 | + undefined_function(); | |
| 1266 | + | |
| 1235 | 1267 | if (1) |
| 1236 | 1268 | return; |
| 1237 | 1269 | printf ("oor:%d\n", undefined_function()); |
| @@ -2544,6 +2576,13 @@ void sizeof_test(void) · 1306 unmodified lines | ||
| 2544 | 2576 | /* And as direct sizeof argument (as unary expression): */ |
| 2545 | 2577 | printf("sizeof (struct {short i; short j;}){4,5} = %d\n", |
| 2546 | 2578 | sizeof (struct {short i; short j;}){4,5} ); |
| 2579 | + | |
| 2580 | + /* sizeof(x && y) should be sizeof(int), even if constant | |
| 2581 | + evaluating is possible. */ | |
| 2582 | + printf("sizeof(t && 0) = %d\n", sizeof(t && 0)); | |
| 2583 | + printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1)); | |
| 2584 | + printf("sizeof(t || 1) = %d\n", sizeof(t || 1)); | |
| 2585 | + printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0)); | |
| 2547 | 2586 | } |
| 2548 | 2587 | |
| 2549 | 2588 | void typeof_test(void) |