aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tccgen.c17
-rw-r--r--tests/tcctest.c10
2 files changed, 27 insertions, 0 deletions
diff --git a/tccgen.c b/tccgen.c
index cd6e690..f79d30e 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -1787,6 +1787,13 @@ static void gen_opic(int op)
gen_opi(op);
} else {
vtop--;
+ /* Ensure vtop isn't marked VT_CONST in case something
+ up our callchain is interested in const-ness of the
+ expression. Also make it a non-LVAL if it was,
+ so that further code can't accidentally generate
+ a deref (happen only for buggy uses of e.g.
+ gv() under nocode_wanted). */
+ vtop->r &= ~(VT_VALMASK | VT_LVAL);
}
}
}
@@ -5014,6 +5021,16 @@ static void expr_cond(void)
}
}
else {
+ /* XXX This doesn't handle nocode_wanted correctly at all.
+ It unconditionally calls gv/gvtst and friends. That's
+ the case for many of the expr_ routines. Currently
+ that should generate only useless code, but depending
+ on other operand handling this might also generate
+ pointer derefs for lvalue conversions whose result
+ is useless, but nevertheless can lead to segfault.
+
+ Somewhen we need to overhaul the whole nocode_wanted
+ handling. */
if (vtop != vstack) {
/* needed to avoid having different registers saved in
each branch */
diff --git a/tests/tcctest.c b/tests/tcctest.c
index b8e534f..daf788c 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -1082,6 +1082,14 @@ static int toupper1(int a)
return TOUPPER(a);
}
+static unsigned int calc_vm_flags(unsigned int prot)
+{
+ unsigned int prot_bits;
+ /* This used to segfault in some revisions: */
+ prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
+ return prot_bits;
+}
+
void bool_test()
{
int *s, a, b, t, f, i;
@@ -1154,6 +1162,7 @@ void bool_test()
if (toupper1 (i) != TOUPPER (i))
printf("error %d\n", i);
}
+ printf ("bits = 0x%x\n", calc_vm_flags (0x1));
}
/* GCC accepts that */
@@ -2880,6 +2889,7 @@ void builtin_test(void)
printf("res = %d\n", __builtin_constant_p(1 + 2));
printf("res = %d\n", __builtin_constant_p(&constant_p_var));
printf("res = %d\n", __builtin_constant_p(constant_p_var));
+ printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var));
s = 1;
ll = 2;
i = __builtin_choose_expr (1 != 0, ll, s);