From: Dan Carpenter Date: Mon, 28 Jan 2013 06:49:57 +0000 (+0300) Subject: modification_hooks: use modification info from the database X-Git-Tag: 1.57~31 X-Git-Url: https://repo.or.cz/w/smatch.git/commitdiff_plain/206be209d6b899efb3eae343d06baef4bd3b69ea modification_hooks: use modification info from the database Add a db callback for when the data is modified. This isn't beautiful. Eventually I think I'd like to get rid of modification_hooks. It sort of duplicates the work done in smatch_extra. Signed-off-by: Dan Carpenter --- diff --git a/smatch_modification_hooks.c b/smatch_modification_hooks.c index 5818a389..7c1c6f71 100644 --- a/smatch_modification_hooks.c +++ b/smatch_modification_hooks.c @@ -91,6 +91,69 @@ free: free_string(name); } +static char *get_variable_from_key(struct expression *arg, char *key, struct symbol **sym) +{ + char buf[256]; + char *tmp; + + if (strcmp(key, "$$") == 0) + return expr_to_var_sym(arg, sym); + + if (strcmp(key, "*$$") == 0) { + if (arg->type == EXPR_PREOP && arg->op == '&') { + arg = strip_expr(arg->unop); + return expr_to_var_sym(arg, sym); + } else { + tmp = expr_to_var_sym(arg, sym); + if (!tmp) + return NULL; + snprintf(buf, sizeof(buf), "*%s", tmp); + free_string(tmp); + return alloc_string(buf); + } + } + + if (arg->type == EXPR_PREOP && arg->op == '&') { + arg = strip_expr(arg->unop); + tmp = expr_to_var_sym(arg, sym); + if (!tmp) + return NULL; + snprintf(buf, sizeof(buf), "%s.%s", tmp, key + 4); + return alloc_string(buf); + } + + tmp = expr_to_var_sym(arg, sym); + if (!tmp) + return NULL; + snprintf(buf, sizeof(buf), "%s%s", tmp, key + 2); + free_string(tmp); + return alloc_string(buf); +} + +static void db_param_add(struct expression *expr, int param, char *key, char *value) +{ + struct expression *arg; + char *name; + struct symbol *sym; + + while (expr->type == EXPR_ASSIGNMENT) + expr = strip_expr(expr->right); + if (expr->type != EXPR_CALL) + return; + + arg = get_argument_from_call_expr(expr->args, param); + if (!arg) + return; + + name = get_variable_from_key(arg, key, &sym); + if (!name || !sym) + goto free; + + call_modification_hooks_name_sym(name, sym); +free: + free_string(name); +} + static void match_assign(struct expression *expr) { call_modification_hooks(expr->left); @@ -155,5 +218,6 @@ void register_modification_hooks(int id) void register_modification_hooks_late(int id) { add_hook(&match_call, FUNCTION_CALL_HOOK); + add_db_return_states_callback(ADDED_VALUE, &db_param_add); }