function_ptr: handle scope of function pointers better
authorDan Carpenter <dan.carpenter@oracle.com>
Fri, 5 Jul 2013 08:41:30 +0000 (5 11:41 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Fri, 5 Jul 2013 08:41:30 +0000 (5 11:41 +0300)
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 <dan.carpenter@oracle.com>
smatch_function_ptrs.c

index 3738805..9173f72 100644 (file)
@@ -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)