Try this patch? regards, dan carpenter >From 04a5ff12178fe7f6cab1eb0e2d370d8dfb17ea2b Mon Sep 17 00:00:00 2001 From: Dan Carpenter <dan.carpenter@xxxxxxxxxx> Date: Mon, 14 Jan 2019 17:35:31 +0300 Subject: [PATCH] implied: Preserve ->hard_max for fake history states In smatch_implied.c we sometimes split an estate (extra state) into two parts to create a fake history. This happens when we have an if statement like "if (x < 10) {" and we hadn't previously known that x=0-9 was an "interesting" range before. Maybe we had only known that x could be in the 0-20 range. So instead of one state, we split it into two states. But unfortunately the ->hard_max information was not preserved so we missed out on some array overflow warnings. Reported-by: John Levon <levon@xxxxxxxxxxxxxxxxx> Signed-off-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx> --- smatch_estate.c | 19 +++++++++++++++++++ smatch_extra.h | 1 + smatch_implied.c | 4 ++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/smatch_estate.c b/smatch_estate.c index 69b84d91..6c3075a4 100644 --- a/smatch_estate.c +++ b/smatch_estate.c @@ -274,6 +274,25 @@ struct smatch_state *clone_estate(struct smatch_state *state) return ret; } +struct smatch_state *clone_partial_estate(struct smatch_state *state, struct range_list *rl) +{ + struct smatch_state *ret; + + if (!state) + return NULL; + + rl = cast_rl(estate_type(state), rl); + + ret = alloc_estate_rl(rl); + set_related(ret, clone_related_list(estate_related(state))); + if (estate_has_hard_max(state)) + estate_set_hard_max(ret); + if (estate_has_fuzzy_max(state)) + estate_set_fuzzy_max(ret, estate_get_fuzzy_max(state)); + + return ret; +} + struct smatch_state *alloc_estate_empty(void) { struct smatch_state *state; diff --git a/smatch_extra.h b/smatch_extra.h index d48cdf1f..e8b350f6 100644 --- a/smatch_extra.h +++ b/smatch_extra.h @@ -117,6 +117,7 @@ struct smatch_state *alloc_estate_rl(struct range_list *rl); struct smatch_state *alloc_estate_whole(struct symbol *type); struct smatch_state *clone_estate(struct smatch_state *state); struct smatch_state *clone_estate_cast(struct symbol *type, struct smatch_state *state); +struct smatch_state *clone_partial_estate(struct smatch_state *state, struct range_list *rl); struct smatch_state *merge_estates(struct smatch_state *s1, struct smatch_state *s2); diff --git a/smatch_implied.c b/smatch_implied.c index 9e36a24c..df00634d 100644 --- a/smatch_implied.c +++ b/smatch_implied.c @@ -149,10 +149,10 @@ static int create_fake_history(struct sm_state *sm, int comparison, struct range true_sm = clone_sm(sm); false_sm = clone_sm(sm); - true_sm->state = alloc_estate_rl(cast_rl(estate_type(sm->state), true_rl)); + true_sm->state = clone_partial_estate(sm->state, true_rl); free_slist(&true_sm->possible); add_possible_sm(true_sm, true_sm); - false_sm->state = alloc_estate_rl(cast_rl(estate_type(sm->state), false_rl)); + false_sm->state = clone_partial_estate(sm->state, false_rl); free_slist(&false_sm->possible); add_possible_sm(false_sm, false_sm); -- 2.17.1