History

Fix type of cond-op

the optimization of a ternary op with two boolean operands had the same problem (as in the last commit) of loosing the type.

Michael Matz committed 3 years ago

Commit ef3eb021 parent 96b31ba2 files · +10 −7Browse files

Unified · Split

2 files
  1. tccgen.c +9 −7
  2. tests/tcctest.c +1 −0
tccgen.c+9−7
@@ -6351,6 +6351,14 @@ static void expr_cond(void) · 6350 unmodified lines
6351 skip(':');6351 skip(':');
6352 expr_cond();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 if (c < 0 && is_cond_bool(vtop) && is_cond_bool(&sv)) {6362 if (c < 0 && is_cond_bool(vtop) && is_cond_bool(&sv)) {
6355 /* optimize "if (f ? a > b : c || d) ..." for example, where normally6363 /* optimize "if (f ? a > b : c || d) ..." for example, where normally
6356 "a < b" and "c || d" would be forced to "(int)0/1" first, whereas6364 "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 /* combine jump targets of 2nd op with VT_CMP of 1st op */6370 /* combine jump targets of 2nd op with VT_CMP of 1st op */
6363 gvtst_set(0, t1);6371 gvtst_set(0, t1);
6364 gvtst_set(1, t2);6372 gvtst_set(1, t2);
6373 gen_cast(&type);
6365 // tcc_warning("two conditions expr_cond");6374 // tcc_warning("two conditions expr_cond");
6366 return;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 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so6378 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
6377 that `(expr ? a : b).mem` does not error with "lvalue expected" */6379 that `(expr ? a : b).mem` does not error with "lvalue expected" */
6378 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);6380 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
tests/tcctest.c+1−0
@@ -1269,6 +1269,7 @@ void bool_test() · 1268 unmodified lines
1269 t = 1;1269 t = 1;
1270 printf("type of bool: %d\n", (int) ( (~ ((unsigned int) (t && 1))) / 2) );1270 printf("type of bool: %d\n", (int) ( (~ ((unsigned int) (t && 1))) / 2) );
1271 1271
1272 printf("type of cond: %d\n", (~(t ? 0U : (unsigned int)0)) / 2 );
1272 /* test ? : cast */1273 /* test ? : cast */
1273 {1274 {
1274 int aspect_on;1275 int aspect_on;

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