From 603bfed3bfd3f5057860b4b805431600c739850f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 17 Mar 2009 11:03:25 +0300 Subject: [PATCH] implied: handle &undefined better foo = NULL; x = 0; if (bar) { foo = frob(); x = 1; } Setting foo = frob() makes it &undefined but we still know that when foo is non zero x == 1. Also set things in smatch_extra to be &undefined earlier. This is not a complete solution because it doesn't deal with globals or members of structures passed as arguments. The way to deal with that is to set those paths retroactively to &undefined in merge_slist(). Signed-off-by: Dan Carpenter --- smatch_extra.c | 35 +++++++++++++++++++++++++---------- smatch_implied.c | 9 +++++++-- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/smatch_extra.c b/smatch_extra.c index 43eed80b..76bd7d0f 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -101,10 +101,24 @@ static void match_declarations(struct symbol *sym) name = sym->ident->name; if (sym->initializer) { set_state(name, my_id, sym, alloc_state(get_value(sym->initializer))); + } else { + set_state(name, my_id, sym, &undefined); } } } +static void match_function_def(struct symbol *sym) +{ + struct symbol *arg; + + FOR_EACH_PTR(sym->ctype.base_type->arguments, arg) { + if (!arg->ident) { + continue; + } + set_state(arg->ident->name, my_id, arg, &undefined); + } END_FOR_EACH_PTR(arg); +} + static void match_unop(struct expression *expr) { struct symbol *sym; @@ -122,16 +136,6 @@ static void match_unop(struct expression *expr) free_string(name); } -void register_smatch_extra(int id) -{ - my_id = id; - add_hook(&undef_expr, OP_HOOK); - add_hook(&match_function_call_after, FUNCTION_CALL_AFTER_HOOK); - add_hook(&match_assign, ASSIGNMENT_AFTER_HOOK); - add_hook(&match_declarations, DECLARATION_HOOK); - add_hook(&match_unop, OP_HOOK); -} - static int expr_to_val(struct expression *expr) { struct smatch_state *state; @@ -277,3 +281,14 @@ int known_condition_false(struct expression *expr) } return 0; } + +void register_smatch_extra(int id) +{ + my_id = id; + add_hook(&undef_expr, OP_HOOK); + add_hook(&match_function_def, FUNC_DEF_HOOK); + add_hook(&match_function_call_after, FUNCTION_CALL_AFTER_HOOK); + add_hook(&match_assign, ASSIGNMENT_AFTER_HOOK); + add_hook(&match_declarations, DECLARATION_HOOK); + add_hook(&match_unop, OP_HOOK); +} diff --git a/smatch_implied.c b/smatch_implied.c index 3c45c768..07ae1c47 100644 --- a/smatch_implied.c +++ b/smatch_implied.c @@ -222,13 +222,18 @@ static void get_eq_neq(struct sm_state *sm_state, int comparison, int num, FOR_EACH_PTR(sm_state->my_pools, list) { s = get_state_slist(list, sm_state->name, sm_state->owner, sm_state->sym); - if (s == &undefined || !s->data) { + if (s == &merged) { free_stack(&true_stack); free_stack(&false_stack); - DIMPLIED("%d '%s' is undefined\n", get_lineno(), + DIMPLIED("%d '%s' is merged.\n", get_lineno(), sm_state->name); return; } + if (s == &undefined) { + push_slist(&true_stack, list); + push_slist(&false_stack, list); + continue; + } if (left) tf = true_comparison(*(int *)s->data, comparison, num); else -- 2.11.4.GIT