introduce: smatch_data/kernel.no_inline_functions
authorDan Carpenter <dan.carpenter@oracle.com>
Thu, 19 Dec 2013 10:57:04 +0000 (19 13:57 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Thu, 19 Dec 2013 10:57:04 +0000 (19 13:57 +0300)
Sometimes you want to be able to handle functions by adding stuff to the
database but the functions get inlined so it doesn't work.  The feature
I'm adding now means that they won't be handled inline.

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

index 9c1333f..c4b48c2 100644 (file)
--- a/smatch.h
+++ b/smatch.h
@@ -372,6 +372,9 @@ extern struct expression *__inline_fn;
 extern int __in_pre_condition;
 extern int __bail_on_rest_of_function;
 
+/* smatch_project.c */
+int is_no_inline_function(const char *function);
+
 /* smatch_conditions */
 void __split_whole_condition(struct expression *expr);
 void __handle_logic(struct expression *expr);
index 0738e99..89fc4b8 100644 (file)
@@ -128,6 +128,8 @@ int inlinable(struct expression *expr)
 
        if (expr->type != EXPR_SYMBOL || !expr->symbol)
                return 0;
+       if (is_no_inline_function(expr->symbol->ident->name))
+               return 0;
        sym = get_base_type(expr->symbol);
        if (sym->stmt && sym->stmt->type == STMT_COMPOUND) {
                if (ptr_list_size((struct ptr_list *)sym->stmt->stmts) <= 10)
index 5b9601b..0511e3c 100644 (file)
@@ -21,6 +21,7 @@
 static DEFINE_HASHTABLE_INSERT(insert_func, char, int);
 static DEFINE_HASHTABLE_SEARCH(search_func, char, int);
 static struct hashtable *silenced_funcs;
+static struct hashtable *no_inline_funcs;
 
 int is_silenced_function(void)
 {
@@ -34,6 +35,13 @@ int is_silenced_function(void)
        return 0;
 }
 
+int is_no_inline_function(const char *function)
+{
+       if (search_func(no_inline_funcs, (char *)function))
+               return 1;
+       return 0;
+}
+
 static void register_no_return_funcs(void)
 {
        struct token *token;
@@ -116,9 +124,40 @@ static void register_silenced_functions(void)
        }
        clear_token_alloc();
 }
+
+static void register_no_inline_functions(void)
+{
+       struct token *token;
+       char *func;
+       char name[256];
+
+       no_inline_funcs = create_function_hashtable(500);
+
+       if (option_project == PROJ_NONE)
+               return;
+
+       snprintf(name, 256, "%s.no_inline_functions", option_project_str);
+
+       token = get_tokens_file(name);
+       if (!token)
+               return;
+       if (token_type(token) != TOKEN_STREAMBEGIN)
+               return;
+       token = token->next;
+       while (token_type(token) != TOKEN_STREAMEND) {
+               if (token_type(token) != TOKEN_IDENT)
+                       return;
+               func = alloc_string(show_ident(token->ident));
+               insert_func(no_inline_funcs, func, INT_PTR(1));
+               token = token->next;
+       }
+       clear_token_alloc();
+}
+
 void register_project(int id)
 {
        register_no_return_funcs();
        register_ignored_macros();
        register_silenced_functions();
+       register_no_inline_functions();
 }