flow: hooks: introduce GLOBAL_ASSIGNMENT_HOOK
authorDan Carpenter <dan.carpenter@oracle.com>
Sat, 17 Nov 2012 13:40:12 +0000 (17 16:40 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Sat, 17 Nov 2012 13:40:12 +0000 (17 16:40 +0300)
It lets you know how global variables are initialized.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch.h
smatch_flow.c
smatch_hooks.c

index ba9df4d..f4a94d1 100644 (file)
--- a/smatch.h
+++ b/smatch.h
@@ -78,6 +78,7 @@ enum hook_type {
        DECLARATION_HOOK,
        ASSIGNMENT_HOOK,
        RAW_ASSIGNMENT_HOOK,
+       GLOBAL_ASSIGNMENT_HOOK,
        LOGIC_HOOK,
        CONDITION_HOOK,
        PRELOOP_HOOK,
index c414d4e..e2d8cfc 100644 (file)
@@ -772,6 +772,30 @@ static void split_declaration(struct symbol_list *sym_list)
        } END_FOR_EACH_PTR(sym);
 }
 
+static void fake_global_assign(struct symbol *sym)
+{
+       struct expression *assign, *symbol;
+
+       if (!sym->initializer)
+               return;
+       if (sym->initializer->type == EXPR_INITIALIZER) {
+               struct expression *deref, *tmp;
+
+               symbol = symbol_expression(sym);
+               FOR_EACH_PTR(sym->initializer->expr_list, tmp) {
+                       if (tmp->type != EXPR_IDENTIFIER) /* how to handle arrays?? */
+                               continue;
+                       deref = deref_expression(symbol, '.', tmp->expr_ident);
+                       assign = assign_expression(deref, tmp->ident_expression);
+                       __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
+               } END_FOR_EACH_PTR(tmp);
+       } else {
+               symbol = symbol_expression(sym);
+               assign = assign_expression(symbol, sym->initializer);
+               __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
+       }
+}
+
 static void split_function(struct symbol *sym)
 {
        struct symbol *base_type = get_base_type(sym);
@@ -847,6 +871,7 @@ static void split_functions(struct symbol_list *sym_list)
                        process_inlines();
                } else {
                        __pass_to_client(sym, BASE_HOOK);
+                       fake_global_assign(sym);
                }
        } END_FOR_EACH_PTR(sym);
        __pass_to_client_no_data(END_FILE_HOOK);
index 080d65a..6817f43 100644 (file)
@@ -62,6 +62,9 @@ void add_hook(void *func, enum hook_type type)
        case RAW_ASSIGNMENT_HOOK:
                container->data_type = EXPR_PTR;
                break;
+       case GLOBAL_ASSIGNMENT_HOOK:
+               container->data_type = EXPR_PTR;
+               break;
        case CALL_ASSIGNMENT_HOOK:
                container->data_type = EXPR_PTR;
                break;