History

Keep lvalue category on structs when evaluating ternary operator

Vlad Vissoultchev committed 10 years ago

Commit 9d778c71 parent 32755db1 file · +17 −4Browse files

Unified · Split

tccgen.c+17−4
@@ -4536,7 +4536,7 @@ static void expr_lor(void) · 4535 unmodified lines
45364536
45374537 static void expr_cond(void)
45384538 {
4539− int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4539+ int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv;
45404540 SValue sv;
45414541 CType type, type1, type2;
45424542
@@ -4655,10 +4655,17 @@ static void expr_cond(void) · 112 unmodified lines
46554655 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
46564656 type.t |= VT_UNSIGNED;
46574657 }
4658−
4658+ /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
4659+ that `(expr ? a : b).mem` does not error with "lvalue expected" */
4660+ islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
4661+
46594662 /* now we convert second operand */
46604663 gen_cast(&type);
4661− if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4664+ if (islv) {
4665+ mk_pointer(&vtop->type);
4666+ gaddrof();
4667+ }
4668+ else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
46624669 gaddrof();
46634670 rc = RC_INT;
46644671 if (is_float(type.t)) {
@@ -4682,12 +4689,18 @@ static void expr_cond(void) · 17 unmodified lines
46824689 /* put again first value and cast it */
46834690 *vtop = sv;
46844691 gen_cast(&type);
4685− if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4692+ if (islv) {
4693+ mk_pointer(&vtop->type);
4694+ gaddrof();
4695+ }
4696+ else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
46864697 gaddrof();
46874698 r1 = gv(rc);
46884699 move_reg(r2, r1, type.t);
46894700 vtop->r = r2;
46904701 gsym(tt);
4702+ if (islv)
4703+ indir();
46914704 }
46924705 }
46934706 }

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