From c061ec04b95bbaa72d05bb048cd593c614d06114 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 21 Feb 2013 14:51:43 +0300 Subject: [PATCH] db: fix call_implies for the in-memory database The call_implies tables is sort of weird. It's only used by check_dereferences_param.c and it might be better to put everything in the return_states table. But on the other hand, fixing this meant adding some useful hooks so it's worthwhile in that sense. Signed-off-by: Dan Carpenter --- check_dereferences_param.c | 3 --- smatch.h | 2 ++ smatch_db.c | 2 +- smatch_flow.c | 2 ++ smatch_hooks.c | 6 ++++++ smatch_returns.c | 18 ++++++++++++++---- validation/sm_inline2.c | 28 ++++++++++++++++++++++++++++ 7 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 validation/sm_inline2.c diff --git a/check_dereferences_param.c b/check_dereferences_param.c index 5e479a3d..6b69ff50 100644 --- a/check_dereferences_param.c +++ b/check_dereferences_param.c @@ -108,9 +108,6 @@ static void process_states(struct state_list *slist) void check_dereferences_param(int id) { - if (!option_info) - return; - my_id = id; add_hook(&match_function_def, FUNC_DEF_HOOK); diff --git a/smatch.h b/smatch.h index 833e4eef..1fe1c357 100644 --- a/smatch.h +++ b/smatch.h @@ -100,6 +100,8 @@ enum hook_type { AFTER_DEF_HOOK, END_FUNC_HOOK, RETURN_HOOK, + INLINE_FN_START, + INLINE_FN_END, END_FILE_HOOK, }; diff --git a/smatch_db.c b/smatch_db.c index aaa4ee52..1bb01b95 100644 --- a/smatch_db.c +++ b/smatch_db.c @@ -931,7 +931,7 @@ void register_definition_db_callbacks(int id) add_hook(&match_end_func_info, END_FUNC_HOOK); add_hook(&match_data_from_db, FUNC_DEF_HOOK); - add_hook(&match_call_implies, FUNCTION_CALL_HOOK); + add_hook(&match_call_implies, CALL_HOOK_AFTER_INLINE); } void register_db_call_marker(int id) diff --git a/smatch_flow.c b/smatch_flow.c index 3fc34f09..1bbffc2f 100644 --- a/smatch_flow.c +++ b/smatch_flow.c @@ -881,6 +881,7 @@ static void parse_inline(struct expression *call) struct symbol *cur_func_sym_bak = cur_func_sym; sm_debug("inline function: %s\n", cur_func); + __pass_to_client(call, INLINE_FN_START); final_pass = 0; /* don't print anything */ __inline_fn = call; @@ -919,6 +920,7 @@ static void parse_inline(struct expression *call) restore_all_states(); set_position(call->pos); __inline_fn = NULL; + __pass_to_client(call, INLINE_FN_END); } static struct symbol_list *inlines_called; diff --git a/smatch_hooks.c b/smatch_hooks.c index 11683a88..745466c7 100644 --- a/smatch_hooks.c +++ b/smatch_hooks.c @@ -128,6 +128,12 @@ void add_hook(void *func, enum hook_type type) case RETURN_HOOK: container->data_type = EXPR_PTR; break; + case INLINE_FN_START: + container->data_type = EXPR_PTR; + break; + case INLINE_FN_END: + container->data_type = EXPR_PTR; + break; case END_FILE_HOOK: /* nothing needed... */ break; diff --git a/smatch_returns.c b/smatch_returns.c index 436af9d8..2ac267a2 100644 --- a/smatch_returns.c +++ b/smatch_returns.c @@ -20,6 +20,7 @@ DECLARE_PTR_LIST(callback_list, struct return_states_callback); static struct callback_list *callback_list; static struct state_list *all_return_states; +static struct state_list_stack *saved_stack; void all_return_states_hook(void (*callback)(struct state_list *slist)) { @@ -40,24 +41,33 @@ static void call_hooks() static void match_return(struct expression *ret_value) { - if (__inline_fn) - return; merge_slist(&all_return_states, __get_cur_slist()); } static void match_end_func(struct symbol *sym) { - if (__inline_fn) - return; merge_slist(&all_return_states, __get_cur_slist()); call_hooks(); free_slist(&all_return_states); } +static void match_save_states(struct expression *expr) +{ + push_slist(&saved_stack, all_return_states); + all_return_states = NULL; +} + +static void match_restore_states(struct expression *expr) +{ + all_return_states = pop_slist(&saved_stack); +} + void register_returns(int id) { my_id = id; add_hook(&match_return, RETURN_HOOK); add_hook(&match_end_func, END_FUNC_HOOK); + add_hook(&match_save_states, INLINE_FN_START); + add_hook(&match_restore_states, INLINE_FN_END); } diff --git a/validation/sm_inline2.c b/validation/sm_inline2.c new file mode 100644 index 00000000..51636452 --- /dev/null +++ b/validation/sm_inline2.c @@ -0,0 +1,28 @@ +#include +#include +#include "check_debug.h" + +int frob(int *x) +{ + *x = *x * 3; + return 0; +} + +int *x; +int main(void) +{ + frob(x); + if (x) + return 1; + return 0; +} + + +/* + * check-name: smatch: inline #2 + * check-command: smatch -I.. sm_inline2.c + * + * check-output-start +sm_inline2.c:15 main() warn: variable dereferenced before check 'x' (see line 14) + * check-output-end + */ -- 2.11.4.GIT