From 54f00fb24794d3251875bc5e1c0ca4013a27e20b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 30 Jun 2021 17:41:10 +0300 Subject: [PATCH] extra: re-write get_long_name_sym() The old code was pretty complicated and slightly buggy. The bug is that it broke out of the loop the first time it found a matching symbol. Another bug is that it doesn't swap the name properly when converting from p = &whatever to p->foo means whatever.foo. When I was thinking about it, what I realized is that probably the most like like thing is that we have: struct whatever *p = some->really->long->thing; So something is assigned to "p" which is also the symbol. So we can look up the symbol and get the long name from that. If p->foo is set to 3 that means some->really->long->thing->foo is set to 3. We can use swap_name() from smatch_param_key.c to simplify the code and because it understands addresses etc. Signed-off-by: Dan Carpenter --- smatch.h | 1 + smatch_extra.c | 54 +++++++++++++++++------------------------------------- smatch_param_key.c | 2 +- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/smatch.h b/smatch.h index 6658f746..598909b4 100644 --- a/smatch.h +++ b/smatch.h @@ -490,6 +490,7 @@ struct expression *get_last_expr_from_expression_stmt(struct expression *expr); #define GLOBAL_SCOPE -4 #define UNKNOWN_SCOPE -5 +char *swap_names(const char *orig, const char *remove, const char *add); char *get_param_var_sym_var_sym(const char *name, struct symbol *sym, struct expression *ret_expr, struct symbol **sym_p); char *get_param_name_sym(struct expression *expr, struct symbol **sym_p); int get_param_key_from_var_sym(const char *name, struct symbol *sym, diff --git a/smatch_extra.c b/smatch_extra.c index b29235fc..25c1c990 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -295,47 +295,27 @@ free: static char *get_long_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym, bool use_stack) { - struct expression *tmp; - struct sm_state *sm; - char buf[256]; - int len, sym_len; - - /* - * Just prepend the name with a different name/sym and return that. - * For example, if we set "foo->bar = bar;" then the other name - * for "bar->baz" is "foo->bar->baz". Or if we have "foo = bar;" then - * the other name for "bar" is "foo". A third option is if we have - * "foo = bar;" then another name for "*bar" is "*foo". - */ + struct expression *orig; + struct symbol *orig_sym; + char *orig_name, *ret; - FOR_EACH_MY_SM(check_assigned_expr_id, __get_cur_stree(), sm) { - tmp = sm->state->data; - if (!tmp || tmp->type != EXPR_SYMBOL) - continue; - if (tmp->symbol == sym) - goto found; - } END_FOR_EACH_SM(sm); - - return NULL; - -found: - len = strlen(name); - sym_len = tmp->symbol->ident->len; - if (!use_stack && sym_len < len && name[sym_len] != '-') + if (!sym || !sym->ident) return NULL; - if (name[0] == '*' && strcmp(name + 1, tmp->symbol_name->name) == 0) - snprintf(buf, sizeof(buf), "*%s", sm->name); - else if (sym_len < len && (name[tmp->symbol->ident->len] == '-' || - name[tmp->symbol->ident->len] == '.')) - snprintf(buf, sizeof(buf), "%s%s", sm->name, name + tmp->symbol->ident->len); - else if (strcmp(name, tmp->symbol_name->name) == 0) - snprintf(buf, sizeof(buf), "%s", sm->name); - else - return NULL; + orig = get_assigned_expr_name_sym(sym->ident->name, sym); + if (orig) { + orig_name = expr_to_var_sym(orig, &orig_sym); + if (!orig_name) + return NULL; - *new_sym = sm->sym; - return alloc_string(buf); + ret = swap_names(name, sym->ident->name, orig_name); + free_string(orig_name); + if (ret) + *new_sym = orig_sym; + return ret; + } + + return NULL; } char *get_other_name_sym_helper(const char *name, struct symbol *sym, struct symbol **new_sym, bool use_stack) diff --git a/smatch_param_key.c b/smatch_param_key.c index b7bc8856..48070f7c 100644 --- a/smatch_param_key.c +++ b/smatch_param_key.c @@ -26,7 +26,7 @@ static void undef(struct sm_state *sm, struct expression *mod_expr) set_state(my_id, sm->name, sm->sym, &undefined); } -static char *swap_names(const char *orig, const char *remove, const char *add) +char *swap_names(const char *orig, const char *remove, const char *add) { char buf[64]; int offset, len, ret; -- 2.11.4.GIT