2 * smatch/smatch_function_ptrs.c
4 * Copyright (C) 2013 Oracle.
6 * Licensed under the Open Software License version 1.1
11 * Track how functions are saved as various struct members or passed as
17 #include "smatch_slist.h"
21 char *get_fnptr_name(struct expression
*expr
)
23 if (expr
->type
== EXPR_SYMBOL
) {
27 param
= get_param_num_from_sym(expr
->symbol
);
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
;
49 FOR_EACH_PTR(expr
->args
, arg
) {
52 tmp
= strip_expr(arg
);
53 if (tmp
->type
== EXPR_PREOP
&& tmp
->op
== '&')
54 tmp
= strip_expr(tmp
->unop
);
56 if (!type
|| type
->type
!= SYM_FN
)
59 called_name
= expr_to_var(expr
->fn
);
62 fn_name
= expr_to_var(tmp
);
66 snprintf(ptr_name
, sizeof(ptr_name
), "%s param %d", called_name
, i
);
67 sql_insert_function_ptr(fn_name
, ptr_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
;
82 if (right
->type
== EXPR_PREOP
&& right
->op
== '&')
83 right
= strip_expr(right
->unop
);
84 if (right
->type
!= EXPR_SYMBOL
)
86 sym
= get_type(right
);
87 if (!sym
|| sym
->type
!= SYM_FN
)
90 fn_name
= expr_to_var(right
);
91 ptr_name
= get_fnptr_name(expr
->left
);
92 if (!fn_name
|| !ptr_name
)
95 sql_insert_function_ptr(fn_name
, ptr_name
);
99 free_string(ptr_name
);
102 void register_function_ptrs(int id
)
109 add_hook(&match_passes_function_pointer
, FUNCTION_CALL_HOOK
);
110 add_hook(&match_function_assign
, ASSIGNMENT_HOOK
);