History

tccgen: fix expr_cond for alt. nocode_wanted

making shure that both the active and the passive branches do exacly the same thing.

grischka committed 9 years ago

Commit e5efd181 parent f843cad1 file · +74 −70Browse files

Unified · Split

tccgen.c+74−70
@@ -5150,72 +5150,62 @@ static int condition_3way(void) · 5149 unmodified lines
5150 5150
5151static void expr_cond(void)5151static 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_645168#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 else5172#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)` so5258 /* 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 having5282 /* 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 first5294 /* 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();

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