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>