From 1cbc2b2f0b2110a85032c24a876e7c2092ce37ab Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 20 May 2013 21:53:41 +0300 Subject: [PATCH] math: create new handle_right_shift() function This uses a totally new algorithm from before but it should work basically the same. Signed-off-by: Dan Carpenter --- smatch_math.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/smatch_math.c b/smatch_math.c index c9e429da..a6ede951 100644 --- a/smatch_math.c +++ b/smatch_math.c @@ -462,6 +462,35 @@ static struct range_list *handle_bitwise_AND(struct expression *expr, int implie return rl_intersection(left_rl, right_rl); } +static struct range_list *handle_right_shift(struct expression *expr, int implied) +{ + struct range_list *left_rl; + sval_t right; + sval_t min, max; + + if (implied == HARD_MAX) + return NULL; + /* this is hopeless without the right side */ + if (!get_implied_value(expr->right, &right)) + return NULL; + left_rl = _get_rl(expr->left, implied); + if (left_rl) { + max = rl_max(left_rl); + min = rl_min(left_rl); + } else { + if (implied_to_rl_enum(implied) == RL_FUZZY) + return NULL; + if (implied_to_rl_enum(implied) == RL_HARD) + return NULL; + max = sval_type_max(get_type(expr->left)); + min = sval_type_val(get_type(expr->left), 0); + } + + max = sval_binop(max, SPECIAL_RIGHTSHIFT, right); + min = sval_binop(min, SPECIAL_RIGHTSHIFT, right); + return alloc_rl(min, max); +} + static struct range_list *handle_known_binop(struct expression *expr) { sval_t left, right; @@ -479,7 +508,6 @@ static struct range_list *handle_binop_rl(struct expression *expr, int implied) struct symbol *type; sval_t left, right; sval_t ret = {.type = &int_ctype, {.value = 123456} }; - int local_undef = 0; int undefined = 0; struct range_list *rl; @@ -495,25 +523,7 @@ static struct range_list *handle_binop_rl(struct expression *expr, int implied) case '&': return handle_bitwise_AND(expr, implied); case SPECIAL_RIGHTSHIFT: - if (implied == HARD_MAX) - return NULL; - left = _get_value(expr->left, &local_undef, implied); - if (local_undef) { - if (implied == IMPLIED_MIN || implied == ABSOLUTE_MIN) { - ret = sval_blank(expr->left); - ret.value = 0; - return alloc_rl(ret, ret); - } - if (implied != IMPLIED_MAX && implied != ABSOLUTE_MAX) - undefined = 1; - if (!get_absolute_max(expr->left, &left)) - undefined = 1; - } - right = _get_value(expr->right, &undefined, implied); - if (undefined) - return NULL; - ret = sval_binop(left, SPECIAL_RIGHTSHIFT, right); - return alloc_rl(ret, ret); + return handle_right_shift(expr, implied); case '-': ret = handle_subtract(expr, &undefined, implied); if (undefined) -- 2.11.4.GIT