From bb3e293a24461e49651e9479a4db193307541dd6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 1 Dec 2014 15:18:45 +0300 Subject: [PATCH] flow: fix how CALL_HOOK_AFTER is called If the a function call is assigned then the call is processed with the assignment. In that case we need to delay calling FUNCTION_CALL_HOOK_AFTER and call it with the assignment as well. I moved the is_assigned_call() to smatch_flow.c so that everyone could use it. Signed-off-by: Dan Carpenter --- smatch.h | 1 + smatch_flow.c | 21 +++++++++++++++++++-- smatch_function_hooks.c | 13 ------------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/smatch.h b/smatch.h index 0123a3ac..aec19da8 100644 --- a/smatch.h +++ b/smatch.h @@ -395,6 +395,7 @@ extern int option_file_output; extern int option_time; extern struct expression_list *big_expression_stack; extern struct statement_list *big_statement_stack; +int is_assigned_call(struct expression *expr); int inlinable(struct expression *expr); extern int __inline_call; extern struct expression *__inline_fn; diff --git a/smatch_flow.c b/smatch_flow.c index 8722edc7..2b27cb1c 100644 --- a/smatch_flow.c +++ b/smatch_flow.c @@ -135,6 +135,19 @@ static void set_position(struct position pos) free(pathname); } +int is_assigned_call(struct expression *expr) +{ + struct expression *tmp; + + FOR_EACH_PTR_REVERSE(big_expression_stack, tmp) { + if (tmp->type == EXPR_ASSIGNMENT && strip_expr(tmp->right) == expr) + return 1; + if (tmp->pos.line < expr->pos.line) + return 0; + } END_FOR_EACH_PTR_REVERSE(tmp); + return 0; +} + static int is_inline_func(struct expression *expr) { if (expr->type != EXPR_SYMBOL || !expr->symbol) @@ -281,8 +294,11 @@ void __split_expr(struct expression *expr) __fake_struct_member_assignments(expr); tmp = strip_expr(expr->right); - if (tmp->type == EXPR_CALL) + if (tmp->type == EXPR_CALL) { __pass_to_client(expr, CALL_ASSIGNMENT_HOOK); + if (!is_fake_call(tmp)) + __pass_to_client(tmp, FUNCTION_CALL_HOOK_AFTER); + } if (get_macro_name(tmp->pos) && get_macro_name(expr->pos) != get_macro_name(tmp->pos)) __pass_to_client(expr, MACRO_ASSIGNMENT_HOOK); @@ -344,7 +360,8 @@ void __split_expr(struct expression *expr) parse_inline(expr); } __pass_to_client(expr, CALL_HOOK_AFTER_INLINE); - __pass_to_client(expr, FUNCTION_CALL_HOOK_AFTER); + if (!is_assigned_call(expr)) + __pass_to_client(expr, FUNCTION_CALL_HOOK_AFTER); if (is_noreturn_func(expr->fn)) nullify_path(); break; diff --git a/smatch_function_hooks.c b/smatch_function_hooks.c index 9d1d5f61..9c8f08f7 100644 --- a/smatch_function_hooks.c +++ b/smatch_function_hooks.c @@ -700,19 +700,6 @@ static void db_return_states(struct expression *expr) call_return_states_after_hooks(); } -static int is_assigned_call(struct expression *expr) -{ - struct expression *tmp; - - FOR_EACH_PTR_REVERSE(big_expression_stack, tmp) { - if (tmp->type == EXPR_ASSIGNMENT && strip_expr(tmp->right) == expr) - return 1; - if (tmp->pos.line < expr->pos.line) - return 0; - } END_FOR_EACH_PTR_REVERSE(tmp); - return 0; -} - static void db_return_states_call(struct expression *expr) { if (is_assigned_call(expr)) -- 2.11.4.GIT