the optimization of a ternary op with two boolean operands had the same problem (as in the last commit) of loosing the type.
Showing the changes to tccgen.c (1 of 2 files). Show all
Unified · Split
| @@ -6351,6 +6351,14 @@ static void expr_cond(void) · 6350 unmodified lines | ||
| 6351 | 6351 | skip(':'); |
| 6352 | 6352 | expr_cond(); |
| 6353 | 6353 | |
| 6354 | + if ((vtop->type.t & VT_BTYPE) == VT_FUNC) | |
| 6355 | + mk_pointer(&vtop->type); | |
| 6356 | + | |
| 6357 | + /* cast operands to correct type according to ISOC rules */ | |
| 6358 | + if (!combine_types(&type, &sv, vtop, '?')) | |
| 6359 | + type_incompatibility_error(&sv.type, &vtop->type, | |
| 6360 | + "type mismatch in conditional expression (have '%s' and '%s')"); | |
| 6361 | + | |
| 6354 | 6362 | if (c < 0 && is_cond_bool(vtop) && is_cond_bool(&sv)) { |
| 6355 | 6363 | /* optimize "if (f ? a > b : c || d) ..." for example, where normally |
| 6356 | 6364 | "a < b" and "c || d" would be forced to "(int)0/1" first, whereas |
| @@ -6362,17 +6370,11 @@ static void expr_cond(void) · 5 unmodified lines | ||
| 6362 | 6370 | /* combine jump targets of 2nd op with VT_CMP of 1st op */ |
| 6363 | 6371 | gvtst_set(0, t1); |
| 6364 | 6372 | gvtst_set(1, t2); |
| 6373 | + gen_cast(&type); | |
| 6365 | 6374 | // tcc_warning("two conditions expr_cond"); |
| 6366 | 6375 | return; |
| 6367 | 6376 | } |
| 6368 | 6377 | |
| 6369 | − if ((vtop->type.t & VT_BTYPE) == VT_FUNC) | |
| 6370 | − mk_pointer(&vtop->type); | |
| 6371 | − | |
| 6372 | − /* cast operands to correct type according to ISOC rules */ | |
| 6373 | − if (!combine_types(&type, &sv, vtop, '?')) | |
| 6374 | − type_incompatibility_error(&sv.type, &vtop->type, | |
| 6375 | − "type mismatch in conditional expression (have '%s' and '%s')"); | |
| 6376 | 6378 | /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so |
| 6377 | 6379 | that `(expr ? a : b).mem` does not error with "lvalue expected" */ |
| 6378 | 6380 | islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE); |