diff options
| author | Vlad Vissoultchev <wqweto@gmail.com> | 2016-03-13 04:32:18 +0200 |
|---|---|---|
| committer | Vlad Vissoultchev <wqweto@gmail.com> | 2016-03-13 04:32:18 +0200 |
| commit | 9d778c7bb68fbc4be1b3d04f752d656ebb906e9f (patch) | |
| tree | 10bfa54a99f3210be1c5e779c26ffd34130d2b43 /tccgen.c | |
| parent | 32755dbea9b5c25993f090e8d49a3c55fccd8e76 (diff) | |
| download | tinycc-9d778c7bb68fbc4be1b3d04f752d656ebb906e9f.tar.gz tinycc-9d778c7bb68fbc4be1b3d04f752d656ebb906e9f.tar.bz2 | |
Keep lvalue category on structs when evaluating ternary operator
Diffstat (limited to 'tccgen.c')
| -rw-r--r-- | tccgen.c | 21 |
1 files changed, 17 insertions, 4 deletions
@@ -4536,7 +4536,7 @@ static void expr_lor(void) static void expr_cond(void) { - int tt, u, r1, r2, rc, t1, t2, bt1, bt2; + int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv; SValue sv; CType type, type1, type2; @@ -4655,10 +4655,17 @@ static void expr_cond(void) (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) type.t |= VT_UNSIGNED; } - + /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so + that `(expr ? a : b).mem` does not error with "lvalue expected" */ + islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE); + /* now we convert second operand */ gen_cast(&type); - if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) + if (islv) { + mk_pointer(&vtop->type); + gaddrof(); + } + else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) gaddrof(); rc = RC_INT; if (is_float(type.t)) { @@ -4682,12 +4689,18 @@ static void expr_cond(void) /* put again first value and cast it */ *vtop = sv; gen_cast(&type); - if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) + if (islv) { + mk_pointer(&vtop->type); + gaddrof(); + } + else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) gaddrof(); r1 = gv(rc); move_reg(r2, r1, type.t); vtop->r = r2; gsym(tt); + if (islv) + indir(); } } } |
