conditions: fix small signedness bug in compares
[smatch.git] / smatch_function_ptrs.c
blob545ab680cd98d00a047693033ab7527109cd54c2
1 /*
2 * smatch/smatch_function_ptrs.c
4 * Copyright (C) 2013 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
11 * Track how functions are saved as various struct members or passed as
12 * parameters.
16 #include "smatch.h"
17 #include "smatch_slist.h"
19 static int my_id;
21 char *get_fnptr_name(struct expression *expr)
23 if (expr->type == EXPR_SYMBOL) {
24 int param;
25 char buf[256];
27 param = get_param_num_from_sym(expr->symbol);
28 if (param >= 0) {
29 snprintf(buf, sizeof(buf), "%s param %d", get_function(), param);
30 return alloc_string(buf);
33 return expr_to_var(expr);
35 return get_member_name(expr);
38 static void match_passes_function_pointer(struct expression *expr)
40 struct expression *arg, *tmp;
41 struct symbol *type;
42 char *called_name;
43 char *fn_name;
44 char ptr_name[256];
45 int i;
48 i = -1;
49 FOR_EACH_PTR(expr->args, arg) {
50 i++;
52 tmp = strip_expr(arg);
53 if (tmp->type == EXPR_PREOP && tmp->op == '&')
54 tmp = strip_expr(tmp->unop);
55 type = get_type(tmp);
56 if (!type || type->type != SYM_FN)
57 continue;
59 called_name = expr_to_var(expr->fn);
60 if (!called_name)
61 return;
62 fn_name = expr_to_var(tmp);
63 if (!fn_name)
64 goto free;
66 snprintf(ptr_name, sizeof(ptr_name), "%s param %d", called_name, i);
67 sql_insert_function_ptr(fn_name, ptr_name);
68 free:
69 free_string(fn_name);
70 free_string(called_name);
71 } END_FOR_EACH_PTR(arg);
75 static void match_function_assign(struct expression *expr)
77 struct expression *right = expr->right;
78 struct symbol *sym;
79 char *fn_name;
80 char *ptr_name;
82 if (right->type == EXPR_PREOP && right->op == '&')
83 right = strip_expr(right->unop);
84 if (right->type != EXPR_SYMBOL)
85 return;
86 sym = get_type(right);
87 if (!sym || sym->type != SYM_FN)
88 return;
90 fn_name = expr_to_var(right);
91 ptr_name = get_fnptr_name(expr->left);
92 if (!fn_name || !ptr_name)
93 goto free;
95 sql_insert_function_ptr(fn_name, ptr_name);
97 free:
98 free_string(fn_name);
99 free_string(ptr_name);
102 void register_function_ptrs(int id)
104 my_id = id;
106 if (!option_info)
107 return;
109 add_hook(&match_passes_function_pointer, FUNCTION_CALL_HOOK);
110 add_hook(&match_function_assign, ASSIGNMENT_HOOK);