From 3058d4116e73062ee2029ad20ecc6f3c3f736915 Mon Sep 17 00:00:00 2001
From: Petr Skocik <pskocik@gmail.com>
Date: Wed, 28 Nov 2018 21:12:38 +0100
Subject: [PATCH] Fix (Cexpr?struct1:struct2).member

Tcc used to fail this with `lvalue expected`
if the expression was a compile-time constant.
---
 tccgen.c                     |  3 +--
 tests/tests2/33_ternary_op.c | 14 ++++++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/tccgen.c b/tccgen.c
index cccd88b4..00777693 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -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;
diff --git a/tests/tests2/33_ternary_op.c b/tests/tests2/33_ternary_op.c
index 8579b502..33cda441 100644
--- a/tests/tests2/33_ternary_op.c
+++ b/tests/tests2/33_ternary_op.c
@@ -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;
 }