linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
To: linux-sparse@vger.kernel.org
Cc: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Subject: [PATCH 4/9] div0: warn on division by zero - general case
Date: Wed, 31 May 2017 05:22:02 +0200	[thread overview]
Message-ID: <20170531032207.95830-5-luc.vanoostenryck@gmail.com> (raw)
In-Reply-To: <20170531032207.95830-1-luc.vanoostenryck@gmail.com>

sparse warn about division by zero but only in plain
expression: no checks are done when the division is
part of a compound assignement.

Change this by adding the appropriate check and warning
during linearization and take care to avoid warning twice.

Note: if should be simpler to drop the checks done at
      expansion time but some expressions are discarded
      before reaching linearization and we want to check
      and warn for those too.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 linearize.c              | 19 +++++++++++++++++++
 validation/div-by-zero.c | 12 ++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/linearize.c b/linearize.c
index 7313e72d8..7760ea996 100644
--- a/linearize.c
+++ b/linearize.c
@@ -959,6 +959,23 @@ static pseudo_t linearize_store_gen(struct entrypoint *ep,
 	return value;
 }
 
+static void warn_undef_insn(struct instruction *insn, int warn)
+{
+	switch (insn->opcode) {
+	case OP_DIVU:
+	case OP_DIVS:
+	case OP_MODU:
+	case OP_MODS:
+		if (is_pseudo_value(insn->src2, 0)) {
+			if (warn)
+				warning(insn->pos, "division by zero");
+		}
+		break;
+	default:
+		break;
+	}
+}
+
 static pseudo_t add_binary_op(struct entrypoint *ep, struct symbol *ctype, int op, pseudo_t left, pseudo_t right)
 {
 	struct instruction *insn = alloc_typed_instruction(op, ctype);
@@ -1208,6 +1225,7 @@ static pseudo_t linearize_assignment(struct entrypoint *ep, struct expression *e
 		oldvalue = cast_pseudo(ep, oldvalue, target->ctype, ctype);
 		opcode = opcode_sign(op_trans[expr->op - SPECIAL_BASE], ctype);
 		dst = add_binary_op(ep, ctype, opcode, oldvalue, value);
+		warn_undef_insn(dst->def, 1);
 		value = cast_pseudo(ep, dst, ctype, expr->ctype);
 	}
 	value = linearize_store_gen(ep, value, &ad);
@@ -1323,6 +1341,7 @@ static pseudo_t linearize_binop(struct entrypoint *ep, struct expression *expr)
 	src2 = linearize_expression(ep, expr->right);
 	op = opcode_sign(opcode[expr->op], expr->ctype);
 	dst = add_binary_op(ep, expr->ctype, op, src1, src2);
+	warn_undef_insn(dst->def, 0);
 	return dst;
 }
 
diff --git a/validation/div-by-zero.c b/validation/div-by-zero.c
index 786e48298..a06944a58 100644
--- a/validation/div-by-zero.c
+++ b/validation/div-by-zero.c
@@ -18,6 +18,14 @@ int isvmod(int a) { return a % (int) 0; }
 int lsvmod(int a) { return a % (long) 0; }
 int usvmod(int a) { return a % (unsigned int) 0; }
 
+int xsvdiv(int a) { if (a && 0) return a / 0; return 0; }
+int asvdiv(int a) { return a /= 0; }
+int osvdiv(int a) { return a / (a && 0); }
+
+int xsvmod(int a) { if (a && 0) return a % 0; return 0; }
+int asvmod(int a) { return a %= 0; }
+int osvmod(int a) { return a % (a && 0); }
+
 /*
  * check-name: div-by-zero.c
  * check-command: sparse -Wno-decl $file
@@ -39,5 +47,9 @@ div-by-zero.c:16:30: warning: division by zero
 div-by-zero.c:17:30: warning: division by zero
 div-by-zero.c:18:30: warning: division by zero
 div-by-zero.c:19:30: warning: division by zero
+div-by-zero.c:21:42: warning: division by zero
+div-by-zero.c:22:33: warning: division by zero
+div-by-zero.c:25:42: warning: division by zero
+div-by-zero.c:26:33: warning: division by zero
  * check-error-end
  */
-- 
2.13.0


  parent reply	other threads:[~2017-05-31  3:22 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-31  3:21 [PATCH 0/9] division by zero warnings Luc Van Oostenryck
2017-05-31  3:21 ` [PATCH 1/9] add is_pseudo_value() Luc Van Oostenryck
2017-05-31  3:22 ` [PATCH 2/9] add a .warned field to struct instruction Luc Van Oostenryck
2017-05-31  3:22 ` [PATCH 3/9] div0: warn on integer divide by 0 also when the lhs is not constant Luc Van Oostenryck
2017-05-31  3:22 ` Luc Van Oostenryck [this message]
2017-05-31  3:22 ` [PATCH 5/9] div0: add warning option -Wdiv-by-zero Luc Van Oostenryck
2017-05-31  3:22 ` [PATCH 6/9] div0: use -Wdiv-by-zero Luc Van Oostenryck
2017-05-31  3:22 ` [PATCH 7/9] div0: warn also during simplification Luc Van Oostenryck
2017-05-31  3:22 ` [PATCH 8/9] div0: warn on float divide by 0 also when the lhs is not constant Luc Van Oostenryck
2017-05-31  3:22 ` [PATCH 9/9] div0: add missing tests for floating point div by zero Luc Van Oostenryck

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=20170531032207.95830-5-luc.vanoostenryck@gmail.com \
    --to=luc.vanoostenryck@gmail.com \
    --cc=linux-sparse@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 NNTP newsgroup(s).