aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/simplify.c
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-06-20 23:52:14 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-08-06 18:30:44 +0200
commit9aa1c8656be5fee7394cb242a80d7ea8eed32385 (patch)
tree499fd2c3b3154ac371873dae541798cab2e021c0 /simplify.c
parentc2a5bd264187f42564b7055bce4cf72a7985cbc5 (diff)
downloadsparse-dev-9aa1c8656be5fee7394cb242a80d7ea8eed32385.tar.gz
bad-shift: wait dead code elimination to warn about bad shifts
Sparse complains when a shift amount is too big for the size of its operand or if it's negative. However, it does this even for expressions that are never evaluated. It's especially annoying in the kernel for type generic macros, for example the ones in arch/*/include/asm/cmpxchg.h So, remove all warnings done at expansion time and avoid any simplifications of such expressions. Same, at linearization and optimization time but in this case mark the instructions as 'tainted' to inhibit any further simplifications. Finally, at the end of the optimization phase, warn for the tainted instructions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'simplify.c')
-rw-r--r--simplify.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/simplify.c b/simplify.c
index 7850bcdc..f6b79685 100644
--- a/simplify.c
+++ b/simplify.c
@@ -754,28 +754,18 @@ static long long check_shift_count(struct instruction *insn, unsigned long long
unsigned int size = insn->size;
long long sval = uval;
+ if (insn->tainted)
+ return -1;
+
if (uval < size)
return uval;
+ insn->tainted = 1;
sval = sign_extend_safe(sval, size);
sval = sign_extend_safe(sval, bits_in_int);
if (sval < 0)
insn->src2 = value_pseudo(sval);
- if (insn->tainted)
- return sval;
-
- if (sval < 0 && Wshift_count_negative)
- warning(insn->pos, "shift count is negative (%lld)", sval);
- if (sval > 0 && Wshift_count_overflow) {
- struct symbol *ctype = insn->type;
- const char *tname;
- if (ctype->type == SYM_NODE)
- ctype = ctype->ctype.base_type;
- tname = show_typename(ctype);
- warning(insn->pos, "shift too big (%llu) for type %s", sval, tname);
- }
- insn->tainted = 1;
- return sval;
+ return -1;
}
static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long value)