From c9d88b4c64920b59d49fa0dc73b8e57649d9a084 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 8 May 2013 16:20:16 +0300 Subject: [PATCH] extra: handle previously assigned simple math This is a special case of this: a = b - 3; if (a < 0) __smatch_implied(b); In this case we know that b is a number greater than 3. The other case where a = b is already handled by the equivalence code. Signed-off-by: Dan Carpenter --- smatch_extra.c | 28 ++++++++++++++++++++++++++-- validation/sm_compare5.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 validation/sm_compare5.c diff --git a/smatch_extra.c b/smatch_extra.c index c7aaa7bf..44ae9b97 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -1024,6 +1024,8 @@ static int opposite_op(int op) static int is_simple_math(struct expression *expr) { + if (!expr) + return 0; if (expr->type != EXPR_BINOP) return 0; if (!opposite_op(expr->op)) @@ -1072,8 +1074,10 @@ static void move_known_values(struct expression **left_p, struct expression **ri static void match_comparison(struct expression *expr) { - struct expression *left = strip_expr(expr->left); - struct expression *right = strip_expr(expr->right); + struct expression *left_orig = strip_expr(expr->left); + struct expression *right_orig = strip_expr(expr->right); + struct expression *left, *right; + struct expression *prev; struct symbol *type; if (match_func_comparison(expr)) @@ -1083,8 +1087,28 @@ static void match_comparison(struct expression *expr) if (!type) type = &llong_ctype; + left = left_orig; + right = right_orig; move_known_values(&left, &right); handle_comparison(type, left, expr->op, right); + + prev = get_assigned_expr(left_orig); + if (is_simple_math(prev)) { + left = prev; + right = right_orig; + move_known_values(&left, &right); + handle_comparison(type, left, expr->op, right); + } + + prev = get_assigned_expr(right_orig); + if (is_simple_math(prev)) { + left = left_orig; + right = prev; + move_known_values(&left, &right); + handle_comparison(type, left, expr->op, right); + } + + } /* this is actually hooked from smatch_implied.c... it's hacky, yes */ diff --git a/validation/sm_compare5.c b/validation/sm_compare5.c new file mode 100644 index 00000000..a5b0e916 --- /dev/null +++ b/validation/sm_compare5.c @@ -0,0 +1,29 @@ +#include "check_debug.h" + +int a, b, c, d; +void func(void) +{ + a = b + 3; + c = d - 3; + + if (a > 10) + return; + __smatch_implied(a); + __smatch_implied(b); + if (10 > c) + return; + __smatch_implied(c); + __smatch_implied(d); +} + +/* + * check-name: Smatch compare #5 + * check-command: smatch -I.. sm_compare5.c + * + * check-output-start +sm_compare5.c:11 func() implied: a = 's32min-10' +sm_compare5.c:12 func() implied: b = 's32min-7' +sm_compare5.c:15 func() implied: c = '10-s32max' +sm_compare5.c:16 func() implied: d = '13-s32max' + * check-output-end + */ -- 2.11.4.GIT