Consider the operation of rounding up to the nearest multiple of a power of 2. e.g. #define ALLOC_SIZE(t) ((sizeof(t) + ASIZE - 1) & ~(ASIZE - 1)) If ASIZE is unfortunately defined as an unsigned type smaller than size_t, then the ~ will not undergo sign-bit extension, and the incorrect mask will be used. If used in a memory allocation context this could be fatal. Warn about such dubious 'large op ~short' usage. Signed-off-by: Phil Carmody <phil@xxxxxxxxxx> --- evaluate.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/evaluate.c b/evaluate.c index 9052962..c0f3c91 100644 --- a/evaluate.c +++ b/evaluate.c @@ -189,6 +189,14 @@ left: return left; } +static int is_bigger_int_type(struct symbol *left, struct symbol *right) +{ + left = integer_promotion(left); + right = integer_promotion(right); + + return (left->bit_size > right->bit_size); +} + static int same_cast_type(struct symbol *orig, struct symbol *new) { return orig->bit_size == new->bit_size && @@ -927,6 +935,19 @@ static struct symbol *evaluate_binop(struct expression *expr) op, right_not ? "!" : ""); + left_not = expr->left->type == EXPR_PREOP + && expr->left->op == '~'; + right_not = expr->right->type == EXPR_PREOP + && expr->right->op == '~'; + if ((left_not && is_bigger_int_type(rtype, ltype) + && (ltype->ctype.modifiers & MOD_UNSIGNED)) || + (right_not && is_bigger_int_type(ltype, rtype) + && (rtype->ctype.modifiers & MOD_UNSIGNED))) + warning(expr->pos, "dubious: %sx %c %sy", + left_not ? "~" : "", + op, + right_not ? "~" : ""); + ltype = usual_conversions(op, expr->left, expr->right, lclass, rclass, ltype, rtype); ctype = rtype = ltype; -- 2.0.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