0 constant can be used as a pointer
This commit is contained in:
38
tcc.c
38
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
|
/* print a type. If 'varstr' is not NULL, then the variable is also
|
||||||
printed in the type */
|
printed in the type */
|
||||||
/* XXX: union */
|
/* XXX: union */
|
||||||
@ -3338,25 +3326,39 @@ void type_to_str(char *buf, int buf_size,
|
|||||||
no_var: ;
|
no_var: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* verify type compatibility to store vtop in 'dt' type, and generate
|
||||||
|
|
||||||
/* verify type compatibility to store vtop in 'st' type, and generate
|
|
||||||
casts if needed. */
|
casts if needed. */
|
||||||
void gen_assign_cast(int dt)
|
void gen_assign_cast(int dt)
|
||||||
{
|
{
|
||||||
int st;
|
int st;
|
||||||
char buf1[256], buf2[256];
|
char buf1[256], buf2[256];
|
||||||
|
|
||||||
st = vtop->t; /* destination type */
|
st = vtop->t; /* source type */
|
||||||
if (!check_assign_types(dt, st)) {
|
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(buf1, sizeof(buf1), st, NULL);
|
||||||
type_to_str(buf2, sizeof(buf2), dt, NULL);
|
type_to_str(buf2, sizeof(buf2), dt, NULL);
|
||||||
error("cannot cast '%s' to '%s'", buf1, buf2);
|
error("cannot cast '%s' to '%s'", buf1, buf2);
|
||||||
}
|
}
|
||||||
|
type_ok:
|
||||||
gen_cast(dt);
|
gen_cast(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* store vtop in lvalue pushed on stack */
|
/* store vtop in lvalue pushed on stack */
|
||||||
void vstore(void)
|
void vstore(void)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user