Add support for skipping functions altogether that smatch can't, or shouldn't, even attempt to process. Signed-off-by: John Levon <john.levon@xxxxxxxxxx> --- smatch.h | 1 + smatch_flow.c | 2 +- smatch_project.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/smatch.h b/smatch.h index 3e5ebe4..b772431 100644 --- a/smatch.h +++ b/smatch.h @@ -202,6 +202,7 @@ extern int option_info; extern int option_spammy; extern char *trace_variable; extern struct stree *global_states; +int is_skipped_function(void); int is_silenced_function(void); /* smatch_impossible.c */ diff --git a/smatch_flow.c b/smatch_flow.c index ca36eaa..5c4d64b 100644 --- a/smatch_flow.c +++ b/smatch_flow.c @@ -1062,7 +1062,7 @@ void __split_stmt(struct statement *stmt) if (!__in_fake_assign) __silence_warnings_for_stmt = false; - if (__bail_on_rest_of_function) + if (__bail_on_rest_of_function || is_skipped_function()) return; if (out_of_memory() || taking_too_long()) { diff --git a/smatch_project.c b/smatch_project.c index b2fa3ce..416445e 100644 --- a/smatch_project.c +++ b/smatch_project.c @@ -28,13 +28,33 @@ static DEFINE_HASHTABLE_INSERT(insert_func, char, int); static DEFINE_HASHTABLE_SEARCH(search_func, char, int); +static struct hashtable *skipped_funcs; static struct hashtable *silenced_funcs; static struct hashtable *no_inline_funcs; +int is_skipped_function(void) +{ + char *func; + + func = get_function(); + if (!func) + return 0; + if (search_func(skipped_funcs, func)) + return 1; + return 0; +} + +/* + * A silenced function will still be processed and potentially appear in info + * output, but not regular checks. + */ int is_silenced_function(void) { char *func; + if (is_skipped_function()) + return 1; + func = get_function(); if (!func) return 0; @@ -101,6 +121,35 @@ static void register_ignored_macros(void) clear_token_alloc(); } +static void register_skipped_functions(void) +{ + struct token *token; + char *func; + char name[256]; + + skipped_funcs = create_function_hashtable(500); + + if (option_project == PROJ_NONE) + return; + + snprintf(name, 256, "%s.skipped_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(skipped_funcs, func, INT_PTR(1)); + token = token->next; + } + clear_token_alloc(); +} + static void register_silenced_functions(void) { struct token *token; @@ -163,6 +212,7 @@ void register_project(int id) { register_no_return_funcs(); register_ignored_macros(); + register_skipped_functions(); register_silenced_functions(); register_no_inline_functions(); } -- 1.8.3.1