From 66edd7efed6caa399deb4bef139a4140ca105f2a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 5 Jul 2013 11:41:30 +0300 Subject: [PATCH] function_ptr: handle scope of function pointers better What happened was that you had a lot of functions which did: fn = SHOULD_WRITE ? write : read; fn(foo, bar, baz); "fn" is a very common name. All those function calls got jumbled together as if they were calling the same function. And also if there were actually a function called "fn", then it thought it was being called as well. In the new code we say that it is "outside_func ptr fn" being called instead of just "fn". This way they don't get mixed up. Signed-off-by: Dan Carpenter --- smatch_function_ptrs.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/smatch_function_ptrs.c b/smatch_function_ptrs.c index 3738805b..9173f721 100644 --- a/smatch_function_ptrs.c +++ b/smatch_function_ptrs.c @@ -13,6 +13,7 @@ * */ +#include "scope.h" #include "smatch.h" #include "smatch_slist.h" @@ -45,6 +46,30 @@ static char *get_array_ptr(struct expression *expr) return alloc_string(buf); } +static int is_local_symbol(struct symbol *sym) +{ + if (!sym || !sym->scope || !sym->scope->token) + return 0; + if (positions_eq(sym->scope->token->pos, cur_func_sym->pos)) + return 1; + return 0; +} + +static char *ptr_prefix(struct symbol *sym) +{ + static char buf[128]; + + + if (is_local_symbol(sym)) + snprintf(buf, sizeof(buf), "%s ptr", get_function()); + else if (sym && toplevel(sym->scope)) + snprintf(buf, sizeof(buf), "%s ptr", get_base_file()); + else + snprintf(buf, sizeof(buf), "ptr"); + + return buf; +} + char *get_fnptr_name(struct expression *expr) { char *name; @@ -68,6 +93,8 @@ char *get_fnptr_name(struct expression *expr) if (expr->type == EXPR_SYMBOL) { int param; char buf[256]; + struct symbol *sym; + struct symbol *type; param = get_param_num_from_sym(expr->symbol); if (param >= 0) { @@ -75,7 +102,16 @@ char *get_fnptr_name(struct expression *expr) return alloc_string(buf); } - return expr_to_var(expr); + name = expr_to_var_sym(expr, &sym); + if (!name) + return NULL; + type = get_type(expr); + if (type && type->type == SYM_PTR) { + snprintf(buf, sizeof(buf), "%s %s", ptr_prefix(sym), name); + free_string(name); + return alloc_string(buf); + } + return name; } name = get_member_name(expr); if (name) @@ -133,7 +169,7 @@ static void match_function_assign(struct expression *expr) right = strip_expr(expr->right); if (right->type == EXPR_PREOP && right->op == '&') right = strip_expr(right->unop); - if (right->type != EXPR_SYMBOL) + if (right->type != EXPR_SYMBOL && right->type != EXPR_DEREF) return; sym = get_type(right); if (!sym) -- 2.11.4.GIT