* [PATCH 3/16] mechanically split compatible_assignment_types()
@ 2007-06-24 8:03 Al Viro
0 siblings, 0 replies; only message in thread
From: Al Viro @ 2007-06-24 8:03 UTC (permalink / raw)
To: linux-sparse
Pure assignment and <op>= cases are different enough to make it easier handling
them in separate functions. For now just split compatible_assignment_types()
in two; the next patches will clean each up.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
evaluate.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 47 insertions(+), 16 deletions(-)
diff --git a/evaluate.c b/evaluate.c
index be67fa8..febfad2 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1130,19 +1130,16 @@ out:
/* FP assignments can not do modulo or bit operations */
static int compatible_float_op(int op)
{
- return op == '=' ||
- op == SPECIAL_ADD_ASSIGN ||
+ return op == SPECIAL_ADD_ASSIGN ||
op == SPECIAL_SUB_ASSIGN ||
op == SPECIAL_MUL_ASSIGN ||
op == SPECIAL_DIV_ASSIGN;
}
-static int compatible_assignment_types(struct expression *expr, struct symbol *target,
- struct expression **rp, struct symbol *source, const char *where, int op)
+static int evaluate_assign_op(struct expression *expr, struct symbol *target,
+ struct expression **rp, struct symbol *source, int op)
{
- const char *typediff;
struct symbol *t, *s;
- int target_as;
int tclass = classify_type(target, &t);
int sclass = classify_type(source, &s);
@@ -1163,20 +1160,49 @@ static int compatible_assignment_types(struct expression *expr, struct symbol *t
return 1;
} else if (!(sclass & TYPE_RESTRICT))
goto Cast;
+ /* source and target would better be identical restricted */
+ if (t == s)
+ return 1;
+ warning(expr->pos, "invalid restricted assignment");
+ *rp = cast_to(*rp, target);
+ return 0;
} else if (tclass & TYPE_PTR) {
if (op == SPECIAL_ADD_ASSIGN || op == SPECIAL_SUB_ASSIGN) {
evaluate_ptr_add(expr, target, rp);
return 1;
}
- if (op != '=') {
- expression_error(expr, "invalid pointer assignment");
- return 0;
- }
- } else if (op != '=') {
+ expression_error(expr, "invalid pointer assignment");
+ return 0;
+ } else {
expression_error(expr, "invalid assignment");
return 0;
}
+Cast:
+ *rp = cast_to(*rp, target);
+ return 1;
+}
+
+static int compatible_assignment_types(struct expression *expr, struct symbol *target,
+ struct expression **rp, struct symbol *source, const char *where)
+{
+ const char *typediff;
+ struct symbol *t, *s;
+ int target_as;
+ int tclass = classify_type(target, &t);
+ int sclass = classify_type(source, &s);
+
+ if (tclass & sclass & TYPE_NUM) {
+ if (tclass & TYPE_RESTRICT) {
+ /* allowed assignments unfoul */
+ if (sclass & TYPE_FOULED && s->ctype.base_type == t)
+ goto Cast;
+ if (!restricted_value(*rp, target))
+ return 1;
+ } else if (!(sclass & TYPE_RESTRICT))
+ 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)
@@ -1268,8 +1294,13 @@ static struct symbol *evaluate_assignment(struct expression *expr)
rtype = degenerate(right);
- if (!compatible_assignment_types(where, ltype, &where->right, rtype, "assignment", expr->op))
- return NULL;
+ if (expr->op != '=') {
+ if (!evaluate_assign_op(where, ltype, &where->right, rtype, expr->op))
+ return NULL;
+ } else {
+ if (!compatible_assignment_types(where, ltype, &where->right, rtype, "assignment"))
+ return NULL;
+ }
evaluate_assign_to(left, ltype);
@@ -1918,7 +1949,7 @@ static int evaluate_arguments(struct symbol *f, struct symbol *fn, struct expres
static char where[30];
examine_symbol_type(target);
sprintf(where, "argument %d", i);
- compatible_assignment_types(expr, target, p, ctype, where, '=');
+ compatible_assignment_types(expr, target, p, ctype, where);
}
i++;
@@ -2307,7 +2338,7 @@ static int handle_simple_initializer(struct expression **ep, int nested,
if (!e->ctype)
return 1;
compatible_assignment_types(e, ctype, ep, degenerate(e),
- "initializer", '=');
+ "initializer");
return 1;
}
@@ -2805,7 +2836,7 @@ static struct symbol *evaluate_return_expression(struct statement *stmt)
}
if (!ctype)
return NULL;
- compatible_assignment_types(expr, fntype, &stmt->expression, ctype, "return expression", '=');
+ compatible_assignment_types(expr, fntype, &stmt->expression, ctype, "return expression");
return NULL;
}
--
1.5.0-rc2.GIT
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2007-06-24 8:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-24 8:03 [PATCH 3/16] mechanically split compatible_assignment_types() 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).