From d02a383a6ac1ace6e46e90c0af953a70ab66ab5d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 28 Sep 2008 06:46:16 +0300 Subject: [PATCH] Handle assignmeents inside conditions better. Signed-off-by: Dan Carpenter --- check_null_deref.c | 20 ++++++++++++++++++++ smatch_states.c | 10 ++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/check_null_deref.c b/check_null_deref.c index d3bc8120..8c6205af 100644 --- a/check_null_deref.c +++ b/check_null_deref.c @@ -63,12 +63,17 @@ static void match_function_call_after(struct expression *expr) } END_FOR_EACH_PTR(tmp); } +static int assign_seen; static void match_assign(struct expression *expr) { struct expression *left; struct symbol *sym; char *name; + if (assign_seen) { + assign_seen--; + return; + } left = strip_expr(expr->left); name = get_variable_from_expr_simple(left, &sym); if (!name) @@ -117,6 +122,21 @@ static void match_condition(struct expression *expr) set_new_true_false_states(name, my_id, sym, &nonnull, &isnull); return; case EXPR_ASSIGNMENT: + assign_seen++; + /* + * There is a kernel macro that does + * for ( ... ; ... || x = NULL ; ) ... + */ + if (is_zero(expr->right)) { + name = get_variable_from_expr_simple(expr->left, &sym); + if (!name) + return; + name = alloc_string(name); + set_new_true_false_states(name, my_id, sym, NULL, &isnull); + return; + } + /* You have to deal with stuff like if (a = b = c) */ + match_condition(expr->right); match_condition(expr->left); return; default: diff --git a/smatch_states.c b/smatch_states.c index 5fdef7ef..8569fb2d 100644 --- a/smatch_states.c +++ b/smatch_states.c @@ -138,10 +138,12 @@ void set_true_false_states(const char *name, int owner, struct symbol *sym, return; } - set_state_slist(&cur_slist, name, owner, sym, true_state); - set_state_stack(&cond_true_stack, name, owner, sym, true_state); - set_state_stack(&cond_false_stack, name, owner, sym, false_state); - + if (true_state) { + set_state_slist(&cur_slist, name, owner, sym, true_state); + set_state_stack(&cond_true_stack, name, owner, sym, true_state); + } + if (false_state) + set_state_stack(&cond_false_stack, name, owner, sym, false_state); } void nullify_path() -- 2.11.4.GIT