aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard>2002-01-03 21:29:54 +0000
committerbellard <bellard>2002-01-03 21:29:54 +0000
commit8b41bc57e1d19c15a688f5d5c20296c460ec8254 (patch)
tree2e30f9e6d8e7a871d1f20a27bad01ac6caed2ab6
parent14658993425878be300aae2e879560698e0c6c4c (diff)
downloadtinycc-8b41bc57e1d19c15a688f5d5c20296c460ec8254.tar.gz
tinycc-8b41bc57e1d19c15a688f5d5c20296c460ec8254.tar.bz2
0 constant can be used as a pointer
-rw-r--r--tcc.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/tcc.c b/tcc.c
index 58de423..117d8a8 100644
--- a/tcc.c
+++ b/tcc.c
@@ -3237,18 +3237,6 @@ int is_compatible_types(int t1, int t2)
}
}
-int check_assign_types(int t1, int t2)
-{
- t1 &= VT_TYPE;
- t2 &= VT_TYPE;
- if ((t1 & VT_BTYPE) == VT_PTR &&
- (t2 & VT_BTYPE) == VT_FUNC) {
- return is_compatible_types(pointed_type(t1), t2);
- } else {
- return is_compatible_types(t1, t2);
- }
-}
-
/* print a type. If 'varstr' is not NULL, then the variable is also
printed in the type */
/* XXX: union */
@@ -3338,25 +3326,39 @@ void type_to_str(char *buf, int buf_size,
no_var: ;
}
-
-
-/* verify type compatibility to store vtop in 'st' type, and generate
+/* verify type compatibility to store vtop in 'dt' type, and generate
casts if needed. */
void gen_assign_cast(int dt)
{
int st;
char buf1[256], buf2[256];
- st = vtop->t; /* destination type */
- if (!check_assign_types(dt, st)) {
+ st = vtop->t; /* source type */
+ if ((dt & VT_BTYPE) == VT_PTR) {
+ /* special cases for pointers */
+ /* a function is implicitely a function pointer */
+ if ((st & VT_BTYPE) == VT_FUNC) {
+ if (!is_compatible_types(pointed_type(dt), st))
+ goto error;
+ else
+ goto type_ok;
+ }
+ /* '0' can also be a pointer */
+ if ((st & VT_BTYPE) == VT_INT &&
+ ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) &&
+ vtop->c.i == 0)
+ goto type_ok;
+ }
+ if (!is_compatible_types(dt, st)) {
+ error:
type_to_str(buf1, sizeof(buf1), st, NULL);
type_to_str(buf2, sizeof(buf2), dt, NULL);
error("cannot cast '%s' to '%s'", buf1, buf2);
}
+ type_ok:
gen_cast(dt);
}
-
/* store vtop in lvalue pushed on stack */
void vstore(void)
{