From ccc51db76c5925f68f107456a4d6ef491ee5144a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 15 May 2012 15:06:11 +0300 Subject: [PATCH] *new* check_dereferences_param: list functions that dereference parameters Make a list of functions that dereference parameters. It goes into the DB. Signed-off-by: Dan Carpenter --- check_dereferences_param.c | 113 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 check_dereferences_param.c diff --git a/check_dereferences_param.c b/check_dereferences_param.c new file mode 100644 index 00000000..27a855e6 --- /dev/null +++ b/check_dereferences_param.c @@ -0,0 +1,113 @@ +/* + * sparse/check_dereferences_param.c + * + * Copyright (C) 2012 Oracle. + * + * Licensed under the Open Software License version 1.1 + * + */ + +#include "smatch.h" +#include "smatch_extra.h" +#include "smatch_slist.h" + +static int my_id; + +STATE(derefed); +STATE(ignore); + +static int is_arg(struct expression *expr) +{ + struct symbol *arg; + + if (expr->type != EXPR_SYMBOL) + return 0; + + FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) { + if (arg == expr->symbol) + return 1; + } END_FOR_EACH_PTR(arg); + return 0; +} + +static void set_ignore(const char *name, struct symbol *sym, struct expression *expr, void *unused) +{ + if (get_state(my_id, name, sym) == &derefed) + return; + set_state(my_id, name, sym, &ignore); +} + +static void match_function_def(struct symbol *sym) +{ + struct symbol *arg; + int i; + + i = -1; + FOR_EACH_PTR(sym->ctype.base_type->arguments, arg) { + i++; + if (!arg->ident) + continue; + add_modification_hook(my_id, arg->ident->name, &set_ignore, NULL); + } END_FOR_EACH_PTR(arg); +} + +static void check_deref(struct expression *expr) +{ + struct sm_state *sm; + + expr = strip_expr(expr); + + if (!is_arg(expr)) + return; + if (implied_not_equal(expr, 0)) + return; + + sm = get_sm_state_expr(my_id, expr); + if (sm && slist_has_state(sm->possible, &ignore)) + return; + set_state_expr(my_id, expr, &derefed); +} + +static void match_dereference(struct expression *expr) +{ + if (expr->type != EXPR_PREOP) + return; + if (getting_address()) + return; + check_deref(expr->unop); +} + +static void set_param_dereferenced(struct expression *arg, char *unused) +{ + check_deref(arg); +} + +static void process_states(struct state_list *slist) +{ + struct symbol *arg; + int i; + + i = -1; + FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) { + i++; + if (!arg->ident) + continue; + if (get_state_slist(slist, my_id, arg->ident->name, arg) == &derefed) + sm_msg("info: dereferences_param %d", i); + } END_FOR_EACH_PTR(arg); +} + +void check_dereferences_param(int id) +{ + if (!option_info) + return; + + my_id = id; + + add_hook(&match_function_def, FUNC_DEF_HOOK); + + add_hook(&match_dereference, DEREF_HOOK); + add_db_fn_call_callback(DEREFERENCE, &set_param_dereferenced); + + all_return_states_hook(&process_states); +} -- 2.11.4.GIT