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