From: Harshvardhan Jha <harshvardhan.jha@oracle.com>
To: smatch@vger.kernel.org
Cc: dan.carpenter@oracle.com, Harshvardhan Jha <harshvardhan.jha@oracle.com>
Subject: [PATCH 1/2] extra: Fix false output of handle_AND_op and handle_AND_condition
Date: Mon, 12 Jul 2021 18:09:46 +0530 [thread overview]
Message-ID: <20210712123947.24116-1-harshvardhan.jha@oracle.com> (raw)
handle_AND_condition and handle_AND_op gave false outputs. This could be
seen in the test case in validation/sm_bits1.c the expected output was
0x1 for possible and 0x0 for definitely set. However, in the previous
state 0x0 was output for both possibly set and definitely set.
Signed-off-by: Harshvardhan Jha <harshvardhan.jha@oracle.com>
---
smatch_expressions.c | 10 ++++++
| 72 +++++++++----------------------------------
validation/sm_bits1.c | 23 ++++++++++++++
3 files changed, 48 insertions(+), 57 deletions(-)
create mode 100644 validation/sm_bits1.c
diff --git a/smatch_expressions.c b/smatch_expressions.c
index 4c36a206..b18e82be 100644
--- a/smatch_expressions.c
+++ b/smatch_expressions.c
@@ -61,6 +61,16 @@ struct expression *value_expr(long long val)
return expr;
}
+struct expression *value_expr_sval(sval_t sval)
+{
+ struct expression *expr;
+
+ expr = alloc_tmp_expression(get_cur_pos(), EXPR_VALUE);
+ expr->value = sval.value;
+ expr->ctype = sval.type;
+ return expr;
+}
+
struct expression *member_expression(struct expression *deref, int op, struct ident *member)
{
struct expression *expr;
--git a/smatch_extra.c b/smatch_extra.c
index b29235fc..e864646a 100644
--- a/smatch_extra.c
+++ b/smatch_extra.c
@@ -2059,24 +2059,6 @@ static void match_comparison(struct expression *expr)
handle_comparison(type, left, expr->op, right);
}
-static sval_t get_high_mask(sval_t known)
-{
- sval_t ret;
- int i;
-
- ret = known;
- ret.value = 0;
-
- for (i = type_bits(known.type) - 1; i >= 0; i--) {
- if (known.uvalue & (1ULL << i))
- ret.uvalue |= (1ULL << i);
- else
- return ret;
-
- }
- return ret;
-}
-
static bool handle_bit_test(struct expression *expr)
{
struct range_list *orig_rl, *rl;
@@ -2122,59 +2104,35 @@ static bool handle_bit_test(struct expression *expr)
return true;
}
-static void handle_AND_op(struct expression *var, sval_t known)
+static void handle_AND_op(struct symbol *type, struct expression *var, sval_t known)
{
- struct range_list *orig_rl;
- struct range_list *true_rl = NULL;
- struct range_list *false_rl = NULL;
- int bit;
- sval_t low_mask = known;
- sval_t high_mask;
- sval_t max;
-
- get_absolute_rl(var, &orig_rl);
+ sval_t sval = { .type = type };
+ struct expression *bits_expr;
- if (known.value > 0) {
- bit = ffsll(known.value) - 1;
- low_mask.uvalue = (1ULL << bit) - 1;
- true_rl = remove_range(orig_rl, sval_type_val(known.type, 0), low_mask);
- }
- high_mask = get_high_mask(known);
- if (high_mask.value) {
- bit = ffsll(high_mask.value) - 1;
- low_mask.uvalue = (1ULL << bit) - 1;
-
- false_rl = orig_rl;
- if (sval_is_negative(rl_min(orig_rl)))
- false_rl = remove_range(false_rl, sval_type_min(known.type), sval_type_val(known.type, -1));
- false_rl = remove_range(false_rl, low_mask, sval_type_max(known.type));
- if (type_signed(high_mask.type) && type_unsigned(rl_type(false_rl))) {
- false_rl = remove_range(false_rl,
- sval_type_val(rl_type(false_rl), sval_type_max(known.type).uvalue),
- sval_type_val(rl_type(false_rl), -1));
- }
- } else if (known.value == 1 &&
- get_hard_max(var, &max) &&
- sval_cmp(max, rl_max(orig_rl)) == 0 &&
- max.value & 1) {
- false_rl = remove_range(orig_rl, max, max);
+ if (known.uvalue == 0) {
+ set_true_false_states_expr(my_id, var, alloc_estate_empty(), NULL);
+ return;
}
- set_extra_expr_true_false(var,
- true_rl ? alloc_estate_rl(true_rl) : NULL,
- false_rl ? alloc_estate_rl(false_rl) : NULL);
+
+ sval.uvalue = 1ULL << (ffsll(known.uvalue) - 1);
+ bits_expr = value_expr_sval(sval);
+ handle_comparison(type, var, SPECIAL_GTE, bits_expr);
}
static void handle_AND_condition(struct expression *expr)
{
sval_t known;
+ struct symbol *type;
if (handle_bit_test(expr))
return;
+ type = get_type(expr);
+
if (get_implied_value(expr->left, &known))
- handle_AND_op(expr->right, known);
+ handle_AND_op(type, expr->right, known);
else if (get_implied_value(expr->right, &known))
- handle_AND_op(expr->left, known);
+ handle_AND_op(type, expr->left, known);
}
static void handle_MOD_condition(struct expression *expr)
diff --git a/validation/sm_bits1.c b/validation/sm_bits1.c
new file mode 100644
index 00000000..a2b75c00
--- /dev/null
+++ b/validation/sm_bits1.c
@@ -0,0 +1,23 @@
+#include "../check_debug.h"
+
+unsigned int frob();
+
+void test(void)
+{
+ unsigned int x = frob();
+ if (x & ~1)
+ return;
+ __smatch_bits(x);
+ __smatch_implied(x);
+}
+
+
+/*
+ * check-name: smatch bits 1
+ * check-command: smatch sm_bits1.c
+ *
+ * check-output-start
+sm_bits1.c:10 test() bit info 'x': definitely set 0x0. possibly set 0x1.
+sm_bits1.c:11 test() implied: x = '0-1'
+ * check-output-end
+ */
--
2.32.0
next reply other threads:[~2021-07-12 12:42 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-12 12:39 Harshvardhan Jha [this message]
2021-07-12 12:39 ` [PATCH 2/2] Fix handle_bit_test so that null set condition is taken care of Harshvardhan Jha
2021-07-12 12:59 ` Dan Carpenter
2021-07-12 12:46 ` [PATCH 1/2] extra: Fix false output of handle_AND_op and handle_AND_condition Dan Carpenter
-- strict thread matches above, loose matches on Subject: below --
2021-07-12 12:54 Harshvardhan Jha
2021-07-12 13:00 ` Dan Carpenter
2021-07-13 12:50 Harshvardhan Jha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210712123947.24116-1-harshvardhan.jha@oracle.com \
--to=harshvardhan.jha@oracle.com \
--cc=dan.carpenter@oracle.com \
--cc=smatch@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).