From 5d61101c7b4dcf7c1166434b90b63961485fefdd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 30 Mar 2015 15:39:29 +0300 Subject: [PATCH] function_hooks: add a hack around in compare_db_return_states_callbacks The problem here is that when we set the state in a fake tree, we also set the state in a real tree. My feeling is that we shouldn't do that but we rely on this behavior in many places. I haven't figured out a good way to fix this. So for now, I'm just adding this very narrow hack around the problem. In function hooks say we set the state on one path but not on the others then it gets set on all the paths because we set the real cur_stree as well. Signed-off-by: Dan Carpenter --- smatch_function_hooks.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/smatch_function_hooks.c b/smatch_function_hooks.c index 9790db91..0e20d5ab 100644 --- a/smatch_function_hooks.c +++ b/smatch_function_hooks.c @@ -443,6 +443,7 @@ static int db_compare_callback(void *_info, int argc, char **argv, char **azColN if (db_info->prev_return_id != -1 && return_id != db_info->prev_return_id) { set_return_state(db_info->var_expr, db_info); stree = __pop_fake_cur_stree(); + if (!db_info->cull) merge_fake_stree(&db_info->stree, stree); free_stree(&stree); @@ -490,6 +491,7 @@ static int db_compare_callback(void *_info, int argc, char **argv, char **azColN static void compare_db_return_states_callbacks(struct expression *left, int comparison, struct expression *right, struct stree *implied_true, struct stree *implied_false) { + struct stree *orig_states; struct stree *stree; struct stree *true_states; struct stree *false_states; @@ -500,6 +502,8 @@ static void compare_db_return_states_callbacks(struct expression *left, int comp struct range_list *rl; int call_on_left; + orig_states = clone_stree(__get_cur_stree()); + /* legacy cruft. need to fix call_implies_callbacks(). */ call_on_left = 1; call_expr = left; @@ -551,6 +555,29 @@ static void compare_db_return_states_callbacks(struct expression *left, int comp free_stree(&stree); false_states = db_info.stree; + /* + * FIXME: This is the biggest hack ever. I need to think about + * how the fake stacks work a lot more. The problem here is that when + * you set the fake stack then it also sets the real stack. That would + * not be a problem in most cases because we normally will just + * overwrite both the true and false states. The problem comes where we + * only overwrite one side, say the true side. Then we use whatever is + * in the cur_stree for the other false side and the cur_stree has part + * of whatever data was set on the true state. + * + * It should be that setting the fake_cur_stree means that the real + * cur_stree stays the same. But for whatever reason that doesn't work. + * We also have many different ways of faking an stree. Sometimes we + * fake everything.... It is a mess. + * + */ + + FOR_EACH_SM(orig_states, sm) { + __set_sm(sm); + } END_FOR_EACH_SM(sm); + + free_stree(&orig_states); + FOR_EACH_SM(true_states, sm) { __set_true_false_sm(sm, NULL); } END_FOR_EACH_SM(sm); @@ -569,7 +596,6 @@ static void compare_db_return_states_callbacks(struct expression *left, int comp FOR_EACH_SM(implied_false, sm) { __set_true_false_sm(NULL, sm); } END_FOR_EACH_SM(sm); - } void function_comparison(struct expression *left, int comparison, struct expression *right) -- 2.11.4.GIT