diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-07-21 12:28:31 +0200 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-07-23 01:40:31 +0200 |
| commit | 9473e0a28653732de602faa35d089d1a2439780e (patch) | |
| tree | 6d52b34d6817216132e5396a4053ff65171ec0a1 | |
| parent | efdefb100d086aaabf20d475c3d1a65cbceeb534 (diff) | |
| download | sparse-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.c | 13 | ||||
| -rw-r--r-- | validation/shift-undef-long.c | 1 |
2 files changed, 8 insertions, 6 deletions
@@ -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 |
