linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).