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