making shure that both the active and the passive branches do exacly the same thing.
Unified · Split
| @@ -5150,72 +5150,62 @@ static int condition_3way(void) · 5149 unmodified lines | ||
| 5150 | 5150 | |
| 5151 | 5151 | static void expr_cond(void) |
| 5152 | 5152 | { |
| 5153 | − int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv; | |
| 5154 | − int c; | |
| 5153 | + int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g; | |
| 5155 | 5154 | SValue sv; |
| 5156 | 5155 | CType type, type1, type2; |
| 5156 | + int saved_nocode_wanted = nocode_wanted; | |
| 5157 | 5157 | |
| 5158 | 5158 | expr_lor(); |
| 5159 | 5159 | if (tok == '?') { |
| 5160 | 5160 | next(); |
| 5161 | 5161 | c = condition_3way(); |
| 5162 | − if (c >= 0) { | |
| 5163 | − int saved_nocode_wanted = nocode_wanted; | |
| 5164 | − if (c) { | |
| 5165 | − if (tok != ':' || !gnu_ext) { | |
| 5166 | − vpop(); | |
| 5167 | − gexpr(); | |
| 5168 | − } | |
| 5169 | − skip(':'); | |
| 5170 | − nocode_wanted = 1; | |
| 5171 | − expr_cond(); | |
| 5172 | − vpop(); | |
| 5173 | − nocode_wanted = saved_nocode_wanted; | |
| 5174 | − } else { | |
| 5175 | − vpop(); | |
| 5176 | − if (tok != ':' || !gnu_ext) { | |
| 5177 | − nocode_wanted = 1; | |
| 5178 | − gexpr(); | |
| 5179 | − vpop(); | |
| 5180 | − nocode_wanted = saved_nocode_wanted; | |
| 5181 | − } | |
| 5182 | − skip(':'); | |
| 5183 | − expr_cond(); | |
| 5184 | − } | |
| 5185 | − } | |
| 5186 | − else { | |
| 5187 | − if (vtop != vstack) { | |
| 5188 | − /* needed to avoid having different registers saved in | |
| 5189 | − each branch */ | |
| 5190 | − if (is_float(vtop->type.t)) { | |
| 5191 | − rc = RC_FLOAT; | |
| 5162 | + g = (tok == ':' && gnu_ext); | |
| 5163 | + if (c < 0) { | |
| 5164 | + /* needed to avoid having different registers saved in | |
| 5165 | + each branch */ | |
| 5166 | + if (is_float(vtop->type.t)) { | |
| 5167 | + rc = RC_FLOAT; | |
| 5192 | 5168 | #ifdef TCC_TARGET_X86_64 |
| 5193 | − if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { | |
| 5194 | − rc = RC_ST0; | |
| 5195 | − } | |
| 5196 | −#endif | |
| 5169 | + if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { | |
| 5170 | + rc = RC_ST0; | |
| 5197 | 5171 | } |
| 5198 | − else | |
| 5199 | − rc = RC_INT; | |
| 5200 | − gv(rc); | |
| 5201 | − save_regs(1); | |
| 5202 | − } | |
| 5203 | − if (tok == ':' && gnu_ext) { | |
| 5172 | +#endif | |
| 5173 | + } else | |
| 5174 | + rc = RC_INT; | |
| 5175 | + save_regs(1); | |
| 5176 | + gv(rc); | |
| 5177 | + if (g) | |
| 5204 | 5178 | gv_dup(); |
| 5205 | − tt = gvtst(1, 0); | |
| 5206 | − } else { | |
| 5207 | − tt = gvtst(1, 0); | |
| 5179 | + tt = gvtst(1, 0); | |
| 5180 | + | |
| 5181 | + } else { | |
| 5182 | + if (!g) | |
| 5183 | + vpop(); | |
| 5184 | + tt = 0; | |
| 5185 | + } | |
| 5186 | + | |
| 5187 | + if (1) { | |
| 5188 | + if (c == 0) | |
| 5189 | + nocode_wanted = 1; | |
| 5190 | + if (!g) | |
| 5208 | 5191 | gexpr(); |
| 5209 | − } | |
| 5192 | + | |
| 5210 | 5193 | type1 = vtop->type; |
| 5211 | 5194 | sv = *vtop; /* save value to handle it later */ |
| 5212 | 5195 | vtop--; /* no vpop so that FP stack is not flushed */ |
| 5213 | 5196 | skip(':'); |
| 5214 | − u = gjmp(0); | |
| 5197 | + | |
| 5198 | + u = 0; | |
| 5199 | + if (c < 0) | |
| 5200 | + u = gjmp(0); | |
| 5215 | 5201 | gsym(tt); |
| 5202 | + nocode_wanted = saved_nocode_wanted; | |
| 5203 | + if (c == 1) | |
| 5204 | + nocode_wanted = 1; | |
| 5216 | 5205 | expr_cond(); |
| 5217 | − type2 = vtop->type; | |
| 5206 | + nocode_wanted = saved_nocode_wanted; | |
| 5218 | 5207 | |
| 5208 | + type2 = vtop->type; | |
| 5219 | 5209 | t1 = type1.t; |
| 5220 | 5210 | bt1 = t1 & VT_BTYPE; |
| 5221 | 5211 | t2 = type2.t; |
| @@ -5224,6 +5214,7 @@ static void expr_cond(void) · 2 unmodified lines | ||
| 5224 | 5214 | if (is_float(bt1) || is_float(bt2)) { |
| 5225 | 5215 | if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { |
| 5226 | 5216 | type.t = VT_LDOUBLE; |
| 5217 | + | |
| 5227 | 5218 | } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) { |
| 5228 | 5219 | type.t = VT_DOUBLE; |
| 5229 | 5220 | } else { |
| @@ -5267,15 +5258,18 @@ static void expr_cond(void) · 37 unmodified lines | ||
| 5267 | 5258 | /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so |
| 5268 | 5259 | that `(expr ? a : b).mem` does not error with "lvalue expected" */ |
| 5269 | 5260 | islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE); |
| 5261 | + islv &= c < 0; | |
| 5270 | 5262 | |
| 5271 | 5263 | /* now we convert second operand */ |
| 5272 | − gen_cast(&type); | |
| 5273 | − if (islv) { | |
| 5274 | − mk_pointer(&vtop->type); | |
| 5275 | − gaddrof(); | |
| 5264 | + if (c != 1) { | |
| 5265 | + gen_cast(&type); | |
| 5266 | + if (islv) { | |
| 5267 | + mk_pointer(&vtop->type); | |
| 5268 | + gaddrof(); | |
| 5269 | + } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) | |
| 5270 | + gaddrof(); | |
| 5276 | 5271 | } |
| 5277 | − else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) | |
| 5278 | − gaddrof(); | |
| 5272 | + | |
| 5279 | 5273 | rc = RC_INT; |
| 5280 | 5274 | if (is_float(type.t)) { |
| 5281 | 5275 | rc = RC_FLOAT; |
| @@ -5287,26 +5281,36 @@ static void expr_cond(void) · 5 unmodified lines | ||
| 5287 | 5281 | } else if ((type.t & VT_BTYPE) == VT_LLONG) { |
| 5288 | 5282 | /* for long longs, we use fixed registers to avoid having |
| 5289 | 5283 | to handle a complicated move */ |
| 5290 | − rc = RC_IRET; | |
| 5284 | + rc = RC_IRET; | |
| 5291 | 5285 | } |
| 5292 | − | |
| 5293 | − r2 = gv(rc); | |
| 5286 | + | |
| 5287 | + tt = r2 = 0; | |
| 5288 | + if (c < 0) { | |
| 5289 | + r2 = gv(rc); | |
| 5290 | + tt = gjmp(0); | |
| 5291 | + } | |
| 5292 | + gsym(u); | |
| 5293 | + | |
| 5294 | 5294 | /* this is horrible, but we must also convert first |
| 5295 | 5295 | operand */ |
| 5296 | − tt = gjmp(0); | |
| 5297 | − gsym(u); | |
| 5298 | − /* put again first value and cast it */ | |
| 5299 | − *vtop = sv; | |
| 5300 | − gen_cast(&type); | |
| 5301 | − if (islv) { | |
| 5302 | − mk_pointer(&vtop->type); | |
| 5303 | − gaddrof(); | |
| 5296 | + vpushv(&sv); | |
| 5297 | + if (c != 2) { | |
| 5298 | + gen_cast(&type); | |
| 5299 | + if (islv) { | |
| 5300 | + mk_pointer(&vtop->type); | |
| 5301 | + gaddrof(); | |
| 5302 | + } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) | |
| 5303 | + gaddrof(); | |
| 5304 | + } | |
| 5305 | + | |
| 5306 | + if (c != 0) | |
| 5307 | + vswap(); | |
| 5308 | + vtop--; | |
| 5309 | + if (c < 0) { | |
| 5310 | + r1 = gv(rc); | |
| 5311 | + move_reg(r2, r1, type.t); | |
| 5312 | + vtop->r = r2; | |
| 5304 | 5313 | } |
| 5305 | − else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) | |
| 5306 | − gaddrof(); | |
| 5307 | − r1 = gv(rc); | |
| 5308 | − move_reg(r2, r1, type.t); | |
| 5309 | − vtop->r = r2; | |
| 5310 | 5314 | gsym(tt); |
| 5311 | 5315 | if (islv) |
| 5312 | 5316 | indir(); |