From 48c2cc03bc3a50de2aaa70ff09cdeef8d03dab2e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Nov 2012 09:39:32 +0300 Subject: [PATCH] math: check for overflows when calculating the max If it overflows then return the max for the type. Signed-off-by: Dan Carpenter --- smatch.h | 1 + smatch_math.c | 14 ++++++++++++++ smatch_sval.c | 17 +++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/smatch.h b/smatch.h index 744918b4..be682653 100644 --- a/smatch.h +++ b/smatch.h @@ -542,6 +542,7 @@ int sval_fits(struct symbol *type, sval_t sval); sval_t sval_cast(struct symbol *type, sval_t sval); sval_t sval_preop(sval_t sval, int op); sval_t sval_binop(sval_t left, int op, sval_t right); +int sval_binop_overflows(sval_t left, int op, sval_t right); const char *sval_to_str(sval_t sval); const char *sval_to_numstr(sval_t sval); sval_t ll_to_sval(long long val); diff --git a/smatch_math.c b/smatch_math.c index a0a62447..c022db8e 100644 --- a/smatch_math.c +++ b/smatch_math.c @@ -226,6 +226,7 @@ static sval_t handle_mod(struct expression *expr, int *undefined, int implied) static sval_t handle_binop(struct expression *expr, int *undefined, int implied) { + struct symbol *type; sval_t left, right; sval_t ret = {.type = &int_ctype, .value = 123456}; int local_undef = 0; @@ -276,6 +277,19 @@ static sval_t handle_binop(struct expression *expr, int *undefined, int implied) if (*undefined) return bogus; + type = get_type(expr); + left = sval_cast(type, left); + right = sval_cast(type, right); + + switch (implied) { + case IMPLIED_MAX: + case FUZZY_MAX: + case HARD_MAX: + case ABSOLUTE_MAX: + if (sval_binop_overflows(left, expr->op, right)) + return sval_type_max(get_type(expr)); + } + switch (expr->op) { case '/': return handle_divide(expr, undefined, implied); diff --git a/smatch_sval.c b/smatch_sval.c index 9500645f..f3c2a19f 100644 --- a/smatch_sval.c +++ b/smatch_sval.c @@ -423,6 +423,23 @@ sval_t sval_binop(sval_t left, int op, sval_t right) return ret; } +int sval_binop_overflows(sval_t left, int op, sval_t right) +{ + sval_t max = sval_type_max(left.type); + + switch (op) { + case '+': + if (sval_cmp(left, sval_binop(max, '-', right)) > 0) + return 1; + return 0; + case '*': + if (sval_cmp(left, sval_binop(max, '/', right)) > 0) + return 1; + return 0; + } + return 0; +} + const char *sval_to_str(sval_t sval) { char buf[30]; -- 2.11.4.GIT