From 49bb5a7e06049c771a28a2cc507c7789dc54a88b Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sat, 3 Sep 2016 23:23:13 +0200 Subject: [PATCH] Fix __builtin_constant_p(1000/x) was incorrectly treated as constant because the vpop removed all traces of non-constness. --- tccgen.c | 17 +++++++++++++++++ tests/tcctest.c | 10 ++++++++++ 2 files changed, 27 insertions(+) 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);