Print this page
11506 smatch resync
@@ -139,10 +139,13 @@
char *get_fnptr_name(struct expression *expr)
{
char *name;
+ if (is_zero(expr))
+ return NULL;
+
expr = strip_expr(expr);
/* (*ptrs[0])(a, b, c) is the same as ptrs[0](a, b, c); */
if (expr->type == EXPR_PREOP && expr->op == '*')
expr = strip_expr(expr->unop);
@@ -343,17 +346,70 @@
return;
snprintf(ptr_name, sizeof(ptr_name), "r %s()", get_function());
sql_insert_function_ptr(fn_name, ptr_name);
}
+static void print_initializer_list(struct expression_list *expr_list,
+ struct symbol *struct_type)
+{
+ struct expression *expr;
+ struct symbol *base_type;
+ char struct_name[256];
+
+ FOR_EACH_PTR(expr_list, expr) {
+ if (expr->type == EXPR_INDEX && expr->idx_expression && expr->idx_expression->type == EXPR_INITIALIZER) {
+ print_initializer_list(expr->idx_expression->expr_list, struct_type);
+ continue;
+ }
+ if (expr->type != EXPR_IDENTIFIER)
+ continue;
+ if (!expr->expr_ident)
+ continue;
+ if (!expr->ident_expression ||
+ expr->ident_expression->type != EXPR_SYMBOL ||
+ !expr->ident_expression->symbol_name)
+ continue;
+ base_type = get_type(expr->ident_expression);
+ if (!base_type || base_type->type != SYM_FN)
+ continue;
+ snprintf(struct_name, sizeof(struct_name), "(struct %s)->%s",
+ struct_type->ident->name, expr->expr_ident->name);
+ sql_insert_function_ptr(expr->ident_expression->symbol_name->name,
+ struct_name);
+ } END_FOR_EACH_PTR(expr);
+}
+
+static void global_variable(struct symbol *sym)
+{
+ struct symbol *struct_type;
+
+ if (!sym->ident)
+ return;
+ if (!sym->initializer || sym->initializer->type != EXPR_INITIALIZER)
+ return;
+ struct_type = get_base_type(sym);
+ if (!struct_type)
+ return;
+ if (struct_type->type == SYM_ARRAY) {
+ struct_type = get_base_type(struct_type);
+ if (!struct_type)
+ return;
+ }
+ if (struct_type->type != SYM_STRUCT || !struct_type->ident)
+ return;
+ print_initializer_list(sym->initializer->expr_list, struct_type);
+}
+
void register_function_ptrs(int id)
{
my_id = id;
if (!option_info)
return;
+ add_hook(&global_variable, BASE_HOOK);
+ add_hook(&global_variable, DECLARATION_HOOK);
add_hook(&match_passes_function_pointer, FUNCTION_CALL_HOOK);
add_hook(&match_returns_function_pointer, RETURN_HOOK);
add_hook(&match_function_assign, ASSIGNMENT_HOOK);
add_hook(&match_function_assign, GLOBAL_ASSIGNMENT_HOOK);
}