* [PATCH 5/8] get compatible_assignment_types() deal with all cases
@ 2007-07-13 17:45 Al Viro
0 siblings, 0 replies; only message in thread
From: Al Viro @ 2007-07-13 17:45 UTC (permalink / raw)
To: linux-sparse
a) pointer to _Bool is OK
b) struct to same struct or union to same union is OK; void to void etc. are not
c) to/from void * with loss of qualifiers or with different address space
should give the right warning itself instead of "different base types"
it would get from fallback to type_difference()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
evaluate.c | 57 +++++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/evaluate.c b/evaluate.c
index 91c7f74..44a4da4 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1259,11 +1259,17 @@ static int compatible_assignment_types(struct expression *expr, struct symbol *t
goto Cast;
if (!restricted_value(*rp, target))
return 1;
+ if (s == t)
+ return 1;
} else if (!(sclass & TYPE_RESTRICT))
goto Cast;
+ typediff = "different base types";
+ goto Err;
}
- if (tclass & TYPE_PTR) {
+ if (tclass == TYPE_PTR) {
+ unsigned long mod1, mod2;
+ struct symbol *b1, *b2;
// NULL pointer is always OK
int is_null = is_null_pointer_constant(*rp);
if (is_null) {
@@ -1271,29 +1277,52 @@ static int compatible_assignment_types(struct expression *expr, struct symbol *t
bad_null(*rp);
goto Cast;
}
- if (sclass & TYPE_PTR && t->ctype.as == s->ctype.as) {
- /* we should be more lazy here */
- int mod1 = t->ctype.modifiers;
- int mod2 = s->ctype.modifiers;
- s = get_base_type(s);
- t = get_base_type(t);
-
+ if (!(sclass & TYPE_PTR)) {
+ typediff = "different base types";
+ goto Err;
+ }
+ /* we should be more lazy here */
+ mod1 = t->ctype.modifiers;
+ mod2 = s->ctype.modifiers;
+ b1 = get_base_type(t);
+ b2 = get_base_type(s);
+ if (b1 == &void_ctype || b2 == &void_ctype) {
/*
* assignments to/from void * are OK, provided that
* we do not remove qualifiers from pointed to [C]
* or mix address spaces [sparse].
*/
- if (!(mod2 & ~mod1 & (MOD_VOLATILE | MOD_CONST)))
- if (s == &void_ctype || t == &void_ctype)
- goto Cast;
+ if (t->ctype.as != s->ctype.as) {
+ typediff = "different address spaces";
+ goto Err;
+ }
+ if (mod2 & ~mod1 & MOD_IGN) {
+ typediff = "different modifiers";
+ goto Err;
+ }
+ goto Cast;
}
+ /* It's OK if the target is more volatile or const than the source */
+ typediff = type_difference(target, source,
+ MOD_VOLATILE | MOD_CONST, 0);
+ if (typediff)
+ goto Err;
+ return 1;
}
- /* It's OK if the target is more volatile or const than the source */
- typediff = type_difference(target, source, MOD_VOLATILE | MOD_CONST, 0);
- if (!typediff)
+ if ((tclass & TYPE_COMPOUND) && s == t)
return 1;
+ if (tclass & TYPE_NUM) {
+ /* XXX: need to turn into comparison with NULL */
+ if (t == &bool_ctype && (sclass & TYPE_PTR))
+ goto Cast;
+ typediff = "different base types";
+ goto Err;
+ }
+ typediff = "invalid types";
+
+Err:
warning(expr->pos, "incorrect type in %s (%s)", where, typediff);
info(expr->pos, " expected %s", show_typename(target));
info(expr->pos, " got %s", show_typename(source));
--
1.5.0-rc2.GIT
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2007-07-13 17:45 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-13 17:45 [PATCH 5/8] get compatible_assignment_types() deal with all cases Al Viro
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).