From 2cf3a6eb4de576baa4875ce707ac0b6302dea0bc Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Thu, 9 Mar 2023 18:18:29 +0100 Subject: [PATCH] Fix more jumpopts (in ternary op) the code in expr_cond save nocode_wanted around some parts of expression evaluation, but at the wrong spots. If the evaluation of the condition itself (e.g. in the testcase the first whole ternary expression) resulted in CODE_OFF, then that was saved, and restored before return, even if in-between codegen would have CODE_ON'ed already. Thus the whole CODE_OFF state bled out to outside the expression evaluation and also disabled the whole if-block. Found by yarpgen v1 (seed 64). --- tccgen.c | 9 ++++----- tests/tests2/33_ternary_op.c | 13 +++++++++++++ tests/tests2/33_ternary_op.expect | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/tccgen.c b/tccgen.c index f493abf4..1e028b3c 100644 --- a/tccgen.c +++ b/tccgen.c @@ -6297,7 +6297,6 @@ static void expr_cond(void) int tt, u, r1, r2, rc, t1, t2, islv, c, g; SValue sv; CType type; - int ncw_prev; expr_lor(); if (tok == '?') { @@ -6320,7 +6319,6 @@ static void expr_cond(void) tt = gvtst(0, 0); } - ncw_prev = nocode_wanted; if (c == 0) nocode_wanted++; if (!g) @@ -6339,7 +6337,8 @@ static void expr_cond(void) } else u = 0; - nocode_wanted = ncw_prev; + if (c == 0) + nocode_wanted--; if (c == 1) nocode_wanted++; skip(':'); @@ -6356,7 +6355,6 @@ static void expr_cond(void) /* combine jump targets of 2nd op with VT_CMP of 1st op */ gvtst_set(0, t1); gvtst_set(1, t2); - nocode_wanted = ncw_prev; // tcc_warning("two conditions expr_cond"); return; } @@ -6394,7 +6392,8 @@ static void expr_cond(void) tt = gjmp(0); } gsym(u); - nocode_wanted = ncw_prev; + if (c == 1) + nocode_wanted--; /* this is horrible, but we must also convert first operand */ diff --git a/tests/tests2/33_ternary_op.c b/tests/tests2/33_ternary_op.c index 1e6b56d6..ee025383 100644 --- a/tests/tests2/33_ternary_op.c +++ b/tests/tests2/33_ternary_op.c @@ -39,6 +39,17 @@ static int getme(struct condstruct* s, int i) return i1 + i2 + i3 + i4; } +int someglobal; + +void constantcond(void) +{ + /* This was broken by 8227db3a2, it saved/restored the CODE_OFF state + during the expression and that bled out to the outer one disabling + codegen for if-body. */ + if (( (someglobal ? 0 : 0) ? 8 : 9)) + printf("okay\n"); +} + int main() { int Count; @@ -73,6 +84,8 @@ int main() //0 ? a : 0.0; } + constantcond(); + return 0; } diff --git a/tests/tests2/33_ternary_op.expect b/tests/tests2/33_ternary_op.expect index 497be0e4..158d02ff 100644 --- a/tests/tests2/33_ternary_op.expect +++ b/tests/tests2/33_ternary_op.expect @@ -10,3 +10,4 @@ 24 27 152 +okay