implied: smatch was saying somethings were implied when they weren't
commit9d6962bad2b6f2a142edf03690bd31d3caf01f25
authorDan Carpenter <dan.carpenter@oracle.com>
Wed, 5 Mar 2014 12:20:10 +0000 (5 15:20 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Wed, 5 Mar 2014 12:20:10 +0000 (5 15:20 +0300)
treebb93253121d465aa73ea52937f169dd6343d4f0c
parent7a8c9bda52f522be2fedabea05f392299637ed22
implied: smatch was saying somethings were implied when they weren't

The real fix is this line:

- if (!is_merged(sm)) {
+ if (!is_merged(sm) || pool_in_pools(sm->pool, keep_stack)) {

The rest of the changes are because I wasn't passing "keep_stack" to the
function originally.

Here is the problematic code:

a = !!b;
if (frob()) {
if (frob_some_more())
a = 1;
}
if (a)
__smatch_about(b);

In the original code smatch_about was saying that "b" had to be non-zero
but actually we don't know what "b" is.

The way smatch implications works is that we look the "if (a) {" condition.
Where "a" comes from is called the ->pool.  We have several pools.
a = 0;
a = 1;
a = the two previous states merged together.
a = the place where we set it to 1 inside the condition.
a = 0-1 merged with 1.
a = 0-1 merged with the previous merge.  This state doesn't have a ->pool
because we haven't merged it with anything.

So we take a look at all the pools of "a" and break them down into places
where the "if (a)" condition would be true or where it is false.

Once we have a list of true and false pools we look at each state in our
cur_stree.  Maybe the state was set recently so we don't know anything
about it.  But maybe it was set before "a" was set and in that case we
might be able to tell what the implications of testing for "if (a)" are.

The problem was that in the original code we were only taking the false
pools into consideration and not the true pools.  We need to consider both.

Reported-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch_implied.c