Re: Odd smatch issue?

Dan Carpenter <[email protected]>
Newsgroups org.kernel.vger.smatch
Message-ID <20190114143800.GF4504@kadam>
Try this patch?

regards,
dan carpenter

From 04a5ff12178fe7f6cab1eb0e2d370d8dfb17ea2b Mon Sep 17 00:00:00 2001
From: Dan Carpenter <[email protected]>
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 <[email protected]>
Signed-off-by: Dan Carpenter <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.