db: extra: param_limit/filter/set: redo value tracing across functions
commit719a7cc5b1553e83972c35f4d5362d4e52bcd1d2
authorDan Carpenter <dan.carpenter@oracle.com>
Tue, 8 Jan 2013 11:28:36 +0000 (8 14:28 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Tue, 8 Jan 2013 11:28:36 +0000 (8 14:28 +0300)
tree059321499a29992666e6c4bb3f9022d46b185f71
parentf493bf4046394a232ce99510f80e86c4f62f50f9
db: extra: param_limit/filter/set: redo value tracing across functions

I recently added some more cross function tracking features for
Smatch and re-implemented the return_implies code.  The problem with the
new version was that if you have a function like this:

int limit(int x)
{
        if (x) {
                x = 0;
                return 1;
        }
        return 0;
}

My new code had two problems.  It said that "x" was always zero on all
return paths.  If you remove the "x = 0" assignment then it said that
x could be any non-zero number if we returned 1.  What I wanted it to
say was that it could be any non-zero number from whatever you pass in.

To fix this I have broken the function tracking into three separate
processes: limit, filter, and set.

Right now limit and filter are used the same way in smatch extra.  The
difference is that limit is used for parameters (stored on the stack) and
filter is used for pointers.

int limit(int x)
{
        if (x) {
                x = 0;
                return 1;
        }
        return 0;
}

limit takes the original value and lets you know what the original was at
the time of the return.  So in this case the return of 1 means that x was
limited to passed in, non-zero values.

Filter and set work like this:

int filter_set(int *x)
{
        if (*x == 52) {
                *x = 42;
                return 1;
        }
        return 0;
}

On the return 1 path none of the original passed in values for *x are
preserved.  *x is set to 42.  On the return 0 path all the original values
except *x == 52 are preserved and no additional values are added.

I had to fix a bug in rl_intersection() and get_member_type_from_key() to
make this work.

I also removed all the support for keeping a record of no side effect
functions.  I don't have a use for that yet and it should be done as a
separate thing anyway.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Makefile
check_list.h
smatch.h
smatch_extra.c
smatch_param_filter.c [new file with mode: 0644]
smatch_param_limit.c
smatch_param_set.c [new file with mode: 0644]
smatch_ranges.c
smatch_scripts/db/fill_db_return_states.pl
smatch_type.c