From c4417a0877302b37aa724dabf67ceb930aa9730e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 11 Sep 2018 14:56:46 +0300 Subject: [PATCH] extra: don't reset impossible states after a condition Say you have "x" set to an empty state, then would do "if (x != 3)" then it was setting the true and false states. We don't want that, we want empty to remain empty. The issue I think is that we started using get_real_absolute_rl() to get the rl. That function retuns the whole rl for empty states. We don't have a way to return an empty rl, only a NULL rl otherwise we'd maybe look at changing get_real_absolute_rl(). This might be the only situation where it matters so maybe this is fine. Signed-off-by: Dan Carpenter --- smatch_extra.c | 13 +++++++++++++ validation/sm_impossible3.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 validation/sm_impossible3.c diff --git a/smatch_extra.c b/smatch_extra.c index 598ae696..1b5463f7 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -1361,6 +1361,16 @@ static int handle_postop_inc(struct expression *left, int op, struct expression return 1; } +static bool is_impossible_variable(struct expression *expr) +{ + struct smatch_state *state; + + state = get_extra_state(expr); + if (state && !estate_rl(state)) + return true; + return false; +} + static void handle_comparison(struct symbol *type, struct expression *left, int op, struct expression *right) { struct range_list *left_orig; @@ -1397,6 +1407,9 @@ static void handle_comparison(struct symbol *type, struct expression *left, int right = strip_parens(right->unop); } + if (is_impossible_variable(left) || is_impossible_variable(right)) + return; + get_real_absolute_rl(left, &left_orig); left_orig = cast_rl(type, left_orig); diff --git a/validation/sm_impossible3.c b/validation/sm_impossible3.c new file mode 100644 index 00000000..40e9e48d --- /dev/null +++ b/validation/sm_impossible3.c @@ -0,0 +1,29 @@ +#include "check_debug.h" + +int frob(void); + +int main(void) +{ + int x; + + x = frob(); + + if (x != -28) + return; + + if (x != -28 && x != -30) + __smatch_implied(x); + __smatch_implied(x); + + return 0; +} + +/* + * check-name: smatch impossible #3 + * check-command: smatch -I.. sm_impossible3.c + * + * check-output-start +sm_impossible3.c:15 main() implied: x = '' +sm_impossible3.c:16 main() implied: x = '(-28)' + * check-output-end + */ -- 2.11.4.GIT