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);
 }