param_set: handle NULL and POISON assignments better
commit2de1369fafaf9d790d81787266ca0e688058958b
authorDan Carpenter <dan.carpenter@oracle.com>
Fri, 8 Jan 2021 08:28:15 +0000 (8 11:28 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Fri, 8 Jan 2021 08:28:15 +0000 (8 11:28 +0300)
tree3c738881c155c733eb8cfc4f5619fd18db73607b
parentd25d5f206eb6c6ee55941c36939bb5dc6d9e1628
param_set: handle NULL and POISON assignments better

The problem with this was that the list_del() function was returning
nonsense information in the cross function database.

The list_del() function looks like this:

static inline void list_del(struct list_head *entry)
{
        __list_del_entry(entry);
        entry->next = LIST_POISON1;
        entry->prev = LIST_POISON2;
}

What Smatch was doing was saying that "entry->next = LIST_POISON1;" gets
translated into one real assignment and a bunch of fake assignments like
"entry->next->prev = fake thing;"  which sets it to unknown.  Then it was
saying that "entry->next->prev->prev = fake thing;" which meant that the
first part goes from unknown to valid pointer.  Which then gets stored in
the cross function DB.

We should say that if "p" is NULL the "p->member" is not a fake unknown but
is instead an empty state.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch.h
smatch_extra.c
smatch_modification_hooks.c
smatch_struct_assignment.c