Fix __builtin_constant_p(1000/x)
was incorrectly treated as constant because the vpop removed all traces of non-constness.
This commit is contained in:
parent
5bd8aeb917
commit
49bb5a7e06
2 changed files with 27 additions and 0 deletions
17
tccgen.c
17
tccgen.c
|
|
@ -1787,6 +1787,13 @@ static void gen_opic(int op)
|
||||||
gen_opi(op);
|
gen_opi(op);
|
||||||
} else {
|
} else {
|
||||||
vtop--;
|
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 {
|
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) {
|
if (vtop != vstack) {
|
||||||
/* needed to avoid having different registers saved in
|
/* needed to avoid having different registers saved in
|
||||||
each branch */
|
each branch */
|
||||||
|
|
|
||||||
|
|
@ -1082,6 +1082,14 @@ static int toupper1(int a)
|
||||||
return TOUPPER(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()
|
void bool_test()
|
||||||
{
|
{
|
||||||
int *s, a, b, t, f, i;
|
int *s, a, b, t, f, i;
|
||||||
|
|
@ -1154,6 +1162,7 @@ void bool_test()
|
||||||
if (toupper1 (i) != TOUPPER (i))
|
if (toupper1 (i) != TOUPPER (i))
|
||||||
printf("error %d\n", i);
|
printf("error %d\n", i);
|
||||||
}
|
}
|
||||||
|
printf ("bits = 0x%x\n", calc_vm_flags (0x1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GCC accepts that */
|
/* 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(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(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;
|
s = 1;
|
||||||
ll = 2;
|
ll = 2;
|
||||||
i = __builtin_choose_expr (1 != 0, ll, s);
|
i = __builtin_choose_expr (1 != 0, ll, s);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue