Fix (Cexpr?struct1:struct2).member

Tcc used to fail this with `lvalue expected`
if the expression was a compile-time constant.
This commit is contained in:
Petr Skocik 2018-11-28 21:12:38 +01:00
parent 9d44b02a49
commit 3058d4116e
2 changed files with 15 additions and 2 deletions

View File

@ -5663,7 +5663,6 @@ static void expr_cond(void)
/* 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);
islv &= c < 0;
/* now we convert second operand */
if (c != 1) {
@ -5708,7 +5707,7 @@ static void expr_cond(void)
gaddrof();
}
if (c < 0) {
if (c < 0 || islv) {
r1 = gv(rc);
move_reg(r2, r1, type.t);
vtop->r = r2;

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <assert.h>
int main()
{
@ -9,6 +10,19 @@ int main()
printf("%d\n", (Count < 5) ? (Count*Count) : (Count * 3));
}
{
int c = 0;
#define ASSERT(X) assert(X)
static struct stru { int x; } a={'A'},b={'B'};
ASSERT('A'==(*(1?&a:&b)).x);
ASSERT('A'==(1?a:b).x);
ASSERT('A'==(c?b:a).x);
ASSERT('A'==(0?b:a).x);
c=1;
ASSERT('A'==(c?a:b).x);
}
return 0;
}