aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Glöckner <daniel-gl@gmx.net>2008-11-20 22:52:35 +0100
committergrischka <grischka>2008-11-30 07:21:49 +0100
commit76b02c2a0308eaf23b43286212bae8c964da2031 (patch)
tree0b2c8961d6fa9db3d750118d7aa3dc1672ad67c3
parent5fd6f7bd44b0d474a11cac9ae70b259f780331f4 (diff)
downloadtinycc-76b02c2a0308eaf23b43286212bae8c964da2031.tar.gz
tinycc-76b02c2a0308eaf23b43286212bae8c964da2031.tar.bz2
Futher changes to casts
nocode_wanted can't be used to enforce constant expressions, as it is set f.ex. by __builtin_constant_p. A null pointer is unequal to a pointer to any object or function. Assuming symbols always point to memory, a symbol+constant cast to bool is always true.
-rw-r--r--tcc.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/tcc.c b/tcc.c
index b0e86cd..c1df2b0 100644
--- a/tcc.c
+++ b/tcc.c
@@ -5975,7 +5975,7 @@ void force_charshort_cast(int t)
/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
static void gen_cast(CType *type)
{
- int sbt, dbt, sf, df, c;
+ int sbt, dbt, sf, df, c, p;
/* special delayed cast for char/short */
/* XXX: in some cases (multiple cascaded casts), it may still
@@ -5997,6 +5997,7 @@ static void gen_cast(CType *type)
sf = is_float(sbt);
df = is_float(dbt);
c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+ p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
if (c) {
/* constant case: we can do it now */
/* XXX: in ISOC, cannot do it if error in convert */
@@ -6053,6 +6054,9 @@ static void gen_cast(CType *type)
vtop->c.i = ((int)vtop->c.ll << s) >> s;
}
}
+ } else if (p && dbt == VT_BOOL) {
+ vtop->r = VT_CONST;
+ vtop->c.i = 1;
} else if (!nocode_wanted) {
/* non constant case: generate code */
if (sf && df) {
@@ -6119,8 +6123,7 @@ static void gen_cast(CType *type)
the lvalue already contains the real type size (see
VT_LVAL_xxx constants) */
}
- } else
- expect("constant expression");
+ }
} else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
/* if we are casting between pointer types,
we must update the VT_LVAL_xxx size */