From e897918b8a275f150048ddd16716a804343c8d14 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 1 Dec 2014 15:57:44 +0300 Subject: [PATCH] core: introduce &ghost state If "foo" is NULL then "foo->bar" is a ghost state. When we merge a ghost state with a &whatever then the result is &whatever. Smatch_extra already has custom unmatched_state and merge functions so it works this way. But really this should be the default for everything. I didn't have a specific reason for this code, but it doesn't seem to cause any false positives. Signed-off-by: Dan Carpenter --- smatch.h | 1 + smatch_helper.c | 3 +++ smatch_slist.c | 4 ++++ smatch_states.c | 1 + 4 files changed, 9 insertions(+) diff --git a/smatch.h b/smatch.h index 3a8835b3..e2956b4d 100644 --- a/smatch.h +++ b/smatch.h @@ -43,6 +43,7 @@ struct smatch_state { }; #define STATE(_x) static struct smatch_state _x = { .name = #_x } extern struct smatch_state undefined; +extern struct smatch_state ghost; extern struct smatch_state merged; extern struct smatch_state true_state; extern struct smatch_state false_state; diff --git a/smatch_helper.c b/smatch_helper.c index d556021f..13677bba 100644 --- a/smatch_helper.c +++ b/smatch_helper.c @@ -649,6 +649,9 @@ int ms_since(struct timeval *start) int parent_is_gone_var_sym(const char *name, struct symbol *sym) { + if (!name || !sym) + return 0; + if (parent_is_null_var_sym(name, sym) || parent_is_free_var_sym(name, sym)) return 1; diff --git a/smatch_slist.c b/smatch_slist.c index bf539587..f030ae57 100644 --- a/smatch_slist.c +++ b/smatch_slist.c @@ -349,6 +349,10 @@ struct smatch_state *merge_states(int owner, const char *name, ret = state1; else if (__has_merge_function(owner)) ret = __client_merge_function(owner, state1, state2); + else if (state1 == &ghost) + ret = state2; + else if (state2 == &ghost) + ret = state1; else if (!state1 || !state2) ret = &undefined; else diff --git a/smatch_states.c b/smatch_states.c index feb29b08..a822c320 100644 --- a/smatch_states.c +++ b/smatch_states.c @@ -38,6 +38,7 @@ #include "smatch_extra.h" struct smatch_state undefined = { .name = "undefined" }; +struct smatch_state ghost = { .name = "ghost" }; struct smatch_state merged = { .name = "merged" }; struct smatch_state true_state = { .name = "true" }; struct smatch_state false_state = { .name = "false" }; -- 2.11.4.GIT