Skip to content

Commit d9ec17d

Browse files
author
DFP
committed
Relaxed the 'incompatible pointer type' warning a bit
Do not emit that warning when the source struct (recursively) contains destination struct as the first member. For example, in this case the warning would have been emitted before, and is not anymore: struct base { int a; }; struct derived { struct base base; int b; }; struct derived derived; struct base *base = &derived; I personally use that pattern in my code (in a bit more elaborate form) and so this change removes the warnings for those use cases, while still retaining it for everything else. Feel free to CC me on the mailing list if you have questions, suggestions or complaints.
1 parent ab2ce3b commit d9ec17d

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

tccgen.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3591,7 +3591,8 @@ static void cast_error(CType *st, CType *dt)
35913591
static void verify_assign_cast(CType *dt)
35923592
{
35933593
CType *st, *type1, *type2;
3594-
int dbt, sbt, qualwarn, lvl;
3594+
Sym *sym;
3595+
int dbt, sbt, qualwarn, lvl, compat;
35953596

35963597
st = &vtop->type; /* source type */
35973598
dbt = dt->t & VT_BTYPE;
@@ -3645,8 +3646,29 @@ static void verify_assign_cast(CType *dt)
36453646
base types, though, in particular for unsigned enums
36463647
and signed int targets. */
36473648
} else {
3648-
tcc_warning("assignment from incompatible pointer type");
3649-
break;
3649+
compat = 0;
3650+
/* Don't warn if the source struct (recursively) contains
3651+
destination struct as the first member. */
3652+
if (dbt == VT_STRUCT && sbt == VT_STRUCT
3653+
&& !IS_UNION(type2->t)
3654+
) {
3655+
sym = type2->ref->next;
3656+
while (sym != NULL && (sym->type.t & VT_BTYPE) == VT_STRUCT
3657+
) {
3658+
if (is_compatible_unqualified_types(type1, &sym->type)
3659+
) {
3660+
compat = 1;
3661+
break;
3662+
}
3663+
if (IS_UNION(sym->type.t))
3664+
break;
3665+
sym = sym->type.ref->next;
3666+
}
3667+
}
3668+
if( !compat ) {
3669+
tcc_warning("assignment from incompatible pointer type");
3670+
break;
3671+
}
36503672
}
36513673
}
36523674
if (qualwarn)

0 commit comments

Comments
 (0)