aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-21 12:28:31 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-23 01:40:31 +0200
commit9473e0a28653732de602faa35d089d1a2439780e (patch)
tree6d52b34d6817216132e5396a4053ff65171ec0a1
parentefdefb100d086aaabf20d475c3d1a65cbceeb534 (diff)
downloadsparse-dev-9473e0a28653732de602faa35d089d1a2439780e.tar.gz
big-shift: do not truncate the count when checking it
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@gmail.com>
-rw-r--r--expand.c13
-rw-r--r--validation/shift-undef-long.c1
2 files changed, 8 insertions, 6 deletions
diff --git a/expand.c b/expand.c
index 669e1de4..5dace8e3 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 50fcd98e..32626743 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