From 2d002be825c42f986911a49b07ea134a1c8029a2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Jan 2013 15:33:08 +0300 Subject: [PATCH] extra, modification_hooks: set "*p" to unknown if we call "function(p)" This only affects people who are not using the smatch_db. Before if you called "foo(&bar)", then it would set "bar" to unknown. Now if you call "foo(bar)" it sets "*bar" to unknown. It does not set "bar->xxx" to unknown. It's awkward that smatch_extra.c and smatch_modification_hooks.c both needed to be modified. There is some cleanup work here that could be done. Signed-off-by: Dan Carpenter --- smatch_extra.c | 37 +++++++++++++++++++++++++++++++++---- smatch_modification_hooks.c | 11 +++++++---- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/smatch_extra.c b/smatch_extra.c index 23c510bf..ab06f4b2 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -402,18 +402,47 @@ static struct smatch_state *unmatched_state(struct sm_state *sm) return alloc_estate_whole(estate_type(sm->state)); } +static void clear_the_pointed_at(struct expression *expr, struct state_list *slist) +{ + char *name; + struct symbol *sym; + struct sm_state *tmp; + + name = expr_to_var_sym(expr, &sym); + if (!name || !sym) + goto free; + + FOR_EACH_PTR(slist, tmp) { + if (tmp->name[0] != '*') + continue; + if (tmp->sym != sym) + continue; + if (strcmp(tmp->name + 1, name) != 0) + continue; + set_extra_mod(tmp->name, tmp->sym, alloc_estate_whole(estate_type(tmp->state))); + } END_FOR_EACH_PTR(tmp); + +free: + free_string(name); +} + static void match_function_call(struct expression *expr) { struct expression *arg; struct expression *tmp; + struct state_list *slist; + + slist = get_all_states(SMATCH_EXTRA); FOR_EACH_PTR(expr->args, arg) { tmp = strip_expr(arg); - if (tmp->type == EXPR_PREOP && tmp->op == '&') { - remove_from_equiv_expr(tmp->unop); - set_state_expr(SMATCH_EXTRA, tmp->unop, alloc_estate_whole(get_type(tmp->unop))); - } + if (tmp->type == EXPR_PREOP && tmp->op == '&') + set_extra_expr_mod(tmp->unop, alloc_estate_whole(get_type(tmp->unop))); + else + clear_the_pointed_at(tmp, slist); } END_FOR_EACH_PTR(arg); + + free_slist(&slist); } static int types_equiv_or_pointer(struct symbol *one, struct symbol *two) diff --git a/smatch_modification_hooks.c b/smatch_modification_hooks.c index 029ec979..09fe7ece 100644 --- a/smatch_modification_hooks.c +++ b/smatch_modification_hooks.c @@ -10,6 +10,7 @@ #include #include #include "smatch.h" +#include "smatch_extra.h" #include "smatch_slist.h" enum { @@ -104,10 +105,12 @@ static void match_call(struct expression *expr) FOR_EACH_PTR(expr->args, arg) { tmp = strip_expr(arg); - if (tmp->type != EXPR_PREOP || tmp->op != '&') - continue; - tmp = strip_expr(tmp->unop); - call_modification_hooks(tmp); + if (tmp->type == EXPR_PREOP && tmp->op == '&') { + tmp = strip_expr(tmp->unop); + call_modification_hooks(tmp); + } else { + call_modification_hooks(deref_expression(tmp)); + } } END_FOR_EACH_PTR(arg); } -- 2.11.4.GIT