[PATCH 10/16] fix index conversions in evaluate_ptr_add()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



index may need to be expanded

Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
---
 evaluate.c |   92 ++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 50 insertions(+), 42 deletions(-)

diff --git a/evaluate.c b/evaluate.c
index 79f1ac9..6cb29ff 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -559,27 +559,12 @@ static int ptr_object_size(struct symbol *ptr_type)
 	return ptr_type->bit_size;
 }
 
-static inline void want_int(struct expression **expr, struct symbol **ctype)
+static struct symbol *evaluate_ptr_add(struct expression *expr, struct symbol *ctype, struct symbol *itype)
 {
-	int class = classify_type((*expr)->ctype, ctype);
-
-	if (!(class & TYPE_RESTRICT))
-		return;
-	warning((*expr)->pos, "restricted degrades to integer");
-	if (class & TYPE_FOULED)	/* unfoul it first */
-		(*ctype) = (*ctype)->ctype.base_type;
-	(*ctype) = (*ctype)->ctype.base_type;	/* get to arithmetic type */
-	*expr = cast_to(*expr, *ctype);
-}
-
-static struct symbol *evaluate_ptr_add(struct expression *expr, struct symbol *ctype, struct expression **ip)
-{
-	struct expression *i = *ip;
-	struct symbol *itype;
+	struct expression *index = expr->right;
+	int multiply;
 	int bit_size;
 
-	want_int(&i, &itype);
-
 	examine_symbol_type(ctype);
 
 	if (!ctype->ctype.base_type) {
@@ -589,31 +574,48 @@ static struct symbol *evaluate_ptr_add(struct expression *expr, struct symbol *c
 
 	/* Get the size of whatever the pointer points to */
 	bit_size = ptr_object_size(ctype);
+	multiply = bit_size >> 3;
+
+	expr->ctype = ctype;
+
+	if (multiply == 1 && itype->bit_size >= bits_in_pointer)
+		return ctype;
 
-	if (bit_size > bits_in_char) {
-		int multiply = bit_size >> 3;
+	if (index->type == EXPR_VALUE) {
 		struct expression *val = alloc_expression(expr->pos, EXPR_VALUE);
+		unsigned long long v = index->value, mask;
+		mask = 1ULL << (itype->bit_size - 1);
+		if (v & mask)
+			v |= -mask;
+		else
+			v &= mask - 1;
+		v *= multiply;
+		mask = 1ULL << (bits_in_pointer - 1);
+		v &= mask | (mask - 1);
+		val->value = v;
+		val->ctype = ssize_t_ctype;
+		expr->right = val;
+		return ctype;
+	}
 
-		if (i->type == EXPR_VALUE) {
-			val->value = i->value * multiply;
-			val->ctype = size_t_ctype;
-			*ip = val;
-		} else {
-			struct expression *mul = alloc_expression(expr->pos, EXPR_BINOP);
+	if (itype->bit_size < bits_in_pointer)
+		index = cast_to(index, ssize_t_ctype);
 
-			val->ctype = size_t_ctype;
-			val->value = bit_size >> 3;
+	if (multiply > 1) {
+		struct expression *val = alloc_expression(expr->pos, EXPR_VALUE);
+		struct expression *mul = alloc_expression(expr->pos, EXPR_BINOP);
 
-			mul->op = '*';
-			mul->ctype = size_t_ctype;
-			mul->left = i;
-			mul->right = val;
+		val->ctype = ssize_t_ctype;
+		val->value = multiply;
 
-			*ip = mul;
-		}
+		mul->op = '*';
+		mul->ctype = ssize_t_ctype;
+		mul->left = index;
+		mul->right = val;
+		index = mul;
 	}
 
-	expr->ctype = ctype;	
+	expr->right = index;
 	return ctype;
 }
 
@@ -919,14 +921,19 @@ static struct symbol *evaluate_binop(struct expression *expr)
 	}
 
 	/* pointer (+|-) integer */
-	if (lclass & TYPE_PTR && is_int(rclass) && (op == '+' || op == '-'))
-		return evaluate_ptr_add(expr, degenerate(expr->left),
-					&expr->right);
+	if (lclass & TYPE_PTR && is_int(rclass) && (op == '+' || op == '-')) {
+		unrestrict(expr->right, rclass, &rtype);
+		return evaluate_ptr_add(expr, degenerate(expr->left), rtype);
+	}
 
 	/* integer + pointer */
-	if (rclass & TYPE_PTR && is_int(lclass) && op == '+')
-		return evaluate_ptr_add(expr, degenerate(expr->right),
-					&expr->left);
+	if (rclass & TYPE_PTR && is_int(lclass) && op == '+') {
+		struct expression *index = expr->left;
+		unrestrict(index, lclass, &ltype);
+		expr->left = expr->right;
+		expr->right = index;
+		return evaluate_ptr_add(expr, degenerate(expr->left), ltype);
+	}
 
 	/* pointer - pointer */
 	if (lclass & rclass & TYPE_PTR && expr->op == '-')
@@ -1118,7 +1125,8 @@ static int evaluate_assign_op(struct expression *expr)
 	}
 	if (tclass & TYPE_PTR && is_int(sclass)) {
 		if (op == SPECIAL_ADD_ASSIGN || op == SPECIAL_SUB_ASSIGN) {
-			evaluate_ptr_add(expr, target, &expr->right);
+			unrestrict(expr->right, sclass, &s);
+			evaluate_ptr_add(expr, target, s);
 			return 1;
 		}
 		expression_error(expr, "invalid pointer assignment");
-- 
1.5.0-rc2.GIT


-
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux