[PATCH 16/17] big-shift: do not truncate the count when checking it

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

 



The function check_shift_count() is used to check the validity
of shift counts but the count is truncated to an (host) int.
This truncated value can thus miss very large (or very negative)
shift count.

Fix this by using the full width shift count when doing the check.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 expand.c                      | 13 ++++++++-----
 validation/shift-undef-long.c |  1 -
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/expand.c b/expand.c
index 669e1de41..5dace8e30 100644
--- a/expand.c
+++ b/expand.c
@@ -158,17 +158,20 @@ Float:
 	expr->type = EXPR_FVALUE;
 }
 
-static void check_shift_count(struct expression *expr, struct symbol *ctype, int count)
+static void check_shift_count(struct expression *expr, struct expression *right)
 {
+	struct symbol *ctype = expr->ctype;
+	long long count = get_longlong(right);
+
 	if (count < 0) {
-		warning(expr->pos, "shift count is negative (%d)", count);
+		warning(expr->pos, "shift count is negative (%lld)", count);
 		return;
 	}
 	if (count < ctype->bit_size)
 		return;
 	if (ctype->type == SYM_NODE)
 		ctype = ctype->ctype.base_type;
-	warning(expr->pos, "shift too big (%u) for type %s", count, show_typename(ctype));
+	warning(expr->pos, "shift too big (%llu) for type %s", count, show_typename(ctype));
 }
 
 /*
@@ -191,7 +194,7 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype)
 	if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) {
 		if (conservative)
 			return 0;
-		check_shift_count(expr, ctype, r);
+		check_shift_count(expr, right);
 	}
 	if (left->type != EXPR_VALUE)
 		return 0;
@@ -573,7 +576,7 @@ static void check_assignment(struct expression *expr)
 		right = expr->right;
 		if (right->type != EXPR_VALUE)
 			break;
-		check_shift_count(expr, expr->ctype, right->value);
+		check_shift_count(expr, right);
 		break;
 	}
 	return;
diff --git a/validation/shift-undef-long.c b/validation/shift-undef-long.c
index 50fcd98eb..326267436 100644
--- a/validation/shift-undef-long.c
+++ b/validation/shift-undef-long.c
@@ -11,7 +11,6 @@ static unsigned very_big_shift(unsigned int a)
 /*
  * check-name: shift-undef-long
  * check-command: sparse -m64 $file
- * check-known-to-fail
  *
  * check-error-start
 shift-undef-long.c:4:16: warning: shift too big (4294967295) for type unsigned int
-- 
2.18.0

--
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