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
51505150
51515151 static void expr_cond(void)
51525152 {
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;
51555154 SValue sv;
51565155 CType type, type1, type2;
5156+ int saved_nocode_wanted = nocode_wanted;
51575157
51585158 expr_lor();
51595159 if (tok == '?') {
51605160 next();
51615161 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;
51925168 #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;
51975171 }
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)
52045178 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)
52085191 gexpr();
5209− }
5192+
52105193 type1 = vtop->type;
52115194 sv = *vtop; /* save value to handle it later */
52125195 vtop--; /* no vpop so that FP stack is not flushed */
52135196 skip(':');
5214− u = gjmp(0);
5197+
5198+ u = 0;
5199+ if (c < 0)
5200+ u = gjmp(0);
52155201 gsym(tt);
5202+ nocode_wanted = saved_nocode_wanted;
5203+ if (c == 1)
5204+ nocode_wanted = 1;
52165205 expr_cond();
5217− type2 = vtop->type;
5206+ nocode_wanted = saved_nocode_wanted;
52185207
5208+ type2 = vtop->type;
52195209 t1 = type1.t;
52205210 bt1 = t1 & VT_BTYPE;
52215211 t2 = type2.t;
@@ -5224,6 +5214,7 @@ static void expr_cond(void) · 2 unmodified lines
52245214 if (is_float(bt1) || is_float(bt2)) {
52255215 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
52265216 type.t = VT_LDOUBLE;
5217+
52275218 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
52285219 type.t = VT_DOUBLE;
52295220 } else {
@@ -5267,15 +5258,18 @@ static void expr_cond(void) · 37 unmodified lines
52675258 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
52685259 that `(expr ? a : b).mem` does not error with "lvalue expected" */
52695260 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
5261+ islv &= c < 0;
52705262
52715263 /* 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();
52765271 }
5277− else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
5278− gaddrof();
5272+
52795273 rc = RC_INT;
52805274 if (is_float(type.t)) {
52815275 rc = RC_FLOAT;
@@ -5287,26 +5281,36 @@ static void expr_cond(void) · 5 unmodified lines
52875281 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
52885282 /* for long longs, we use fixed registers to avoid having
52895283 to handle a complicated move */
5290− rc = RC_IRET;
5284+ rc = RC_IRET;
52915285 }
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+
52945294 /* this is horrible, but we must also convert first
52955295 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;
53045313 }
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;
53105314 gsym(tt);
53115315 if (islv)
53125316 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