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 | expr_or(); | 4910 | expr_or(); |
| 4911 | if (tok == TOK_LAND) { | 4911 | if (tok == TOK_LAND) { |
| 4912 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 4912 | int t = 0; |
| 4913 | CType ctb, cti; | 4913 | for(;;) { |
| 4914 | ctb.t = VT_BOOL; | 4914 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 4915 | cti.t = VT_INT; | 4915 | CType ctb; |
| 4916 | next(); | 4916 | ctb.t = VT_BOOL; |
| 4917 | gen_cast(&ctb); | 4917 | gen_cast(&ctb); |
| 4918 | if (vtop->c.i) { | 4918 | if (vtop->c.i) { |
| 4919 | vpop(); | 4919 | vpop(); |
| 4920 | expr_land(); | 4920 | } else { |
| 4921 | gen_cast(&ctb); | 4921 | int saved_nocode_wanted = nocode_wanted; |
| 4922 | } else { | 4922 | nocode_wanted = 1; |
| 4923 | int saved_nocode_wanted = nocode_wanted; | 4923 | while (tok == TOK_LAND) { |
| 4924 | nocode_wanted = 1; | 4924 | next(); |
| 4925 | expr_land(); | 4925 | expr_or(); |
| 4926 | vpop(); | 4926 | vpop(); |
| 4927 | nocode_wanted = saved_nocode_wanted; | 4927 | } |
| 4928 | } | 4928 | if (t) |
| 4929 | gen_cast(&cti); | 4929 | gsym(t); |
| 4930 | } else { | 4930 | nocode_wanted = saved_nocode_wanted; |
| 4931 | int t = 0; | 4931 | gen_cast(&int_type); |
| 4932 | save_regs(1); | 4932 | break; |
| 4933 | for(;;) { | 4933 | } |
| 4934 | t = gvtst(1, t); | 4934 | } else { |
| 4935 | if (tok != TOK_LAND) { | 4935 | if (!t) |
| 4936 | vseti(VT_JMPI, t); | 4936 | save_regs(1); |
| 4937 | break; | 4937 | t = gvtst(1, t); |
| 4938 | } | 4938 | } |
| 4939 | next(); | 4939 | if (tok != TOK_LAND) { |
| 4940 | expr_or(); | 4940 | if (t) |
| 4941 | } | 4941 | vseti(VT_JMPI, t); |
| 4942 | } | 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 | expr_land(); | 4954 | expr_land(); |
| 4949 | if (tok == TOK_LOR) { | 4955 | if (tok == TOK_LOR) { |
| 4950 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 4956 | int t = 0; |
| 4951 | CType ctb, cti; | 4957 | for(;;) { |
| 4952 | ctb.t = VT_BOOL; | 4958 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 4953 | cti.t = VT_INT; | 4959 | CType ctb; |
| 4954 | next(); | 4960 | ctb.t = VT_BOOL; |
| 4955 | gen_cast(&ctb); | 4961 | gen_cast(&ctb); |
| 4956 | if (vtop->c.i) { | 4962 | if (!vtop->c.i) { |
| 4957 | int saved_nocode_wanted = nocode_wanted; | 4963 | vpop(); |
| 4958 | nocode_wanted = 1; | 4964 | } else { |
| 4959 | expr_lor(); | 4965 | int saved_nocode_wanted = nocode_wanted; |
| 4960 | vpop(); | 4966 | nocode_wanted = 1; |
| 4961 | nocode_wanted = saved_nocode_wanted; | 4967 | while (tok == TOK_LOR) { |
| 4962 | } else { | 4968 | next(); |
| 4963 | vpop(); | 4969 | expr_land(); |
| 4964 | expr_lor(); | 4970 | vpop(); |
| 4965 | gen_cast(&ctb); | 4971 | } |
| 4966 | } | 4972 | if (t) |
| 4967 | gen_cast(&cti); | 4973 | gsym(t); |
| 4968 | } else { | 4974 | nocode_wanted = saved_nocode_wanted; |
| 4969 | int t = 0; | 4975 | gen_cast(&int_type); |
| 4970 | save_regs(1); | 4976 | break; |
| 4971 | for(;;) { | 4977 | } |
| 4972 | t = gvtst(0, t); | 4978 | } else { |
| 4973 | if (tok != TOK_LOR) { | 4979 | if (!t) |
| 4974 | vseti(VT_JMP, t); | 4980 | save_regs(1); |
| 4975 | break; | 4981 | t = gvtst(0, t); |
| 4976 | } | 4982 | } |
| 4977 | next(); | 4983 | if (tok != TOK_LOR) { |
| 4978 | expr_land(); | 4984 | if (t) |
| 4979 | } | 4985 | vseti(VT_JMP, t); |
| 4980 | } | 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 | printf("ool6:%d\n", defined_function()); | 1232 | printf("ool6:%d\n", defined_function()); |
| 1233 | goto breakhere; | 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 | if (1) | 1267 | if (1) |
| 1236 | return; | 1268 | return; |
| 1237 | printf ("oor:%d\n", undefined_function()); | 1269 | printf ("oor:%d\n", undefined_function()); |
| @@ -2544,6 +2576,13 @@ void sizeof_test(void) · 1306 unmodified lines | |||
| 2544 | /* And as direct sizeof argument (as unary expression): */ | 2576 | /* And as direct sizeof argument (as unary expression): */ |
| 2545 | printf("sizeof (struct {short i; short j;}){4,5} = %d\n", | 2577 | printf("sizeof (struct {short i; short j;}){4,5} = %d\n", |
| 2546 | sizeof (struct {short i; short j;}){4,5} ); | 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 | void typeof_test(void) | 2588 | void typeof_test(void) |