From a54ac829a66d7a74e967cd3915091e03547606bf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 16 Feb 2016 13:53:39 +0300 Subject: [PATCH] implied: fall out from fake_cur_stree changes This basically only affect check_leaks.c. That check wants to set the true false states but then the implication code overwrites it with something less specific. This wasn't an issue before when we used to set the cur stree whenever we set the true path, but now it is. Fixes: 6e9820f295e2 ('states: __set_sm_cur_stree() should not change the fake_cur_stree()') Signed-off-by: Dan Carpenter --- smatch.h | 1 + smatch_implied.c | 4 ++-- smatch_slist.c | 13 +++++++++++++ smatch_slist.h | 2 ++ smatch_states.c | 16 ++++++++++++++++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/smatch.h b/smatch.h index b03fd429..83684d2d 100644 --- a/smatch.h +++ b/smatch.h @@ -556,6 +556,7 @@ void __set_sm_cur_stree(struct sm_state *sm); void __use_orig_if_not_set(struct sm_state *sm); void __set_true_false_sm(struct sm_state *true_state, struct sm_state *false_state); +void __set_true_false_sm_if_not_already_set(struct sm_state *true_sm, struct sm_state *false_sm); void nullify_path(void); void __match_nullify_path_hook(const char *fn, struct expression *expr, void *unused); diff --git a/smatch_implied.c b/smatch_implied.c index 08d2478e..dda4662f 100644 --- a/smatch_implied.c +++ b/smatch_implied.c @@ -596,12 +596,12 @@ static void set_implied_states(struct expression *expr) } END_FOR_EACH_SM(sm); FOR_EACH_SM(saved_implied_true, sm) { - __set_true_false_sm(sm, NULL); + __set_true_false_sm_if_not_already_set(sm, NULL); } END_FOR_EACH_SM(sm); free_stree(&saved_implied_true); FOR_EACH_SM(saved_implied_false, sm) { - __set_true_false_sm(NULL, sm); + __set_true_false_sm_if_not_already_set(NULL, sm); } END_FOR_EACH_SM(sm); free_stree(&saved_implied_false); } diff --git a/smatch_slist.c b/smatch_slist.c index 55becc96..bd9f7ca8 100644 --- a/smatch_slist.c +++ b/smatch_slist.c @@ -449,6 +449,19 @@ void overwrite_sm_state_stree_stack(struct stree_stack **stack, push_stree(stack, stree); } +void set_sm_state_stree_stack_if_not_already_set(struct stree_stack **stack, + struct sm_state *sm) +{ + struct stree *stree; + + stree = pop_stree(stack); + if (get_state_stree(stree, sm->owner, sm->name, sm->sym)) + goto push; + overwrite_sm_state_stree(&stree, sm); +push: + push_stree(stack, stree); +} + struct sm_state *set_state_stree(struct stree **stree, int owner, const char *name, struct symbol *sym, struct smatch_state *state) { diff --git a/smatch_slist.h b/smatch_slist.h index 3d2e9398..fdfa3ff0 100644 --- a/smatch_slist.h +++ b/smatch_slist.h @@ -44,6 +44,8 @@ struct sm_state *get_sm_state_stree(struct stree *stree, int owner, const char * void overwrite_sm_state_stree(struct stree **stree, struct sm_state *sm); void overwrite_sm_state_stree_stack(struct stree_stack **stack, struct sm_state *sm); +void set_sm_state_stree_stack_if_not_already_set(struct stree_stack **stack, + struct sm_state *sm); struct sm_state *set_state_stree(struct stree **stree, int owner, const char *name, struct symbol *sym, struct smatch_state *state); void set_state_stree_perm(struct stree **stree, int owner, const char *name, diff --git a/smatch_states.c b/smatch_states.c index 1ae7b4e7..a85fb4e1 100644 --- a/smatch_states.c +++ b/smatch_states.c @@ -479,6 +479,22 @@ void __set_true_false_sm(struct sm_state *true_sm, struct sm_state *false_sm) overwrite_sm_state_stree_stack(&cond_false_stack, false_sm); } +void __set_true_false_sm_if_not_already_set(struct sm_state *true_sm, struct sm_state *false_sm) +{ + if (unreachable()) + return; + + if (!cond_false_stack || !cond_true_stack) { + printf("Error: missing true/false stacks\n"); + return; + } + + if (true_sm) + set_sm_state_stree_stack_if_not_already_set(&cond_true_stack, true_sm); + if (false_sm) + set_sm_state_stree_stack_if_not_already_set(&cond_false_stack, false_sm); +} + void nullify_path(void) { free_stree(&cur_stree); -- 2.11.4.GIT