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: Chris Li <sparse@chrisli.org>,
	Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Subject: [PATCH v2 3/8] div0: warn on integer divide by 0 also when the lhs is not constant
Date: Sat,  3 Jun 2017 10:01:30 +0200	[thread overview]
Message-ID: <20170603080135.46477-4-luc.vanoostenryck@gmail.com> (raw)
In-Reply-To: <20170603080135.46477-1-luc.vanoostenryck@gmail.com>

The current code detects and warns on division by zero but
only when the left-hand side is a constant value.

Fix that by moving up the code which detect such divisions
before checking if the LHS is a constant.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 expand.c                 |  8 ++----
 validation/div-by-zero.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 6 deletions(-)
 create mode 100644 validation/div-by-zero.c

diff --git a/expand.c b/expand.c
index 5f908c971..0b528ea5a 100644
--- a/expand.c
+++ b/expand.c
@@ -181,6 +181,8 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype)
 	if (right->type != EXPR_VALUE)
 		return 0;
 	r = right->value;
+	if (!r && (expr->op == '/' || expr->op == '%'))
+		goto Div;
 	if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) {
 		if (r >= ctype->bit_size) {
 			if (conservative)
@@ -235,28 +237,22 @@ static int simplify_int_binop(struct expression *expr, struct symbol *ctype)
 		break;
 
 	case SIGNED('/'):
-		if (!r)
-			goto Div;
 		if (l == mask && sr == -1)
 			goto Overflow;
 		v = sl / sr;
 		break;
 
 	case UNSIGNED('/'):
-		if (!r) goto Div;
 		v = l / r; 
 		break;
 
 	case SIGNED('%'):
-		if (!r)
-			goto Div;
 		if (l == mask && sr == -1)
 			goto Overflow;
 		v = sl % sr;
 		break;
 
 	case UNSIGNED('%'):
-		if (!r) goto Div;
 		v = l % r;
 		break;
 
diff --git a/validation/div-by-zero.c b/validation/div-by-zero.c
new file mode 100644
index 000000000..500ceb8eb
--- /dev/null
+++ b/validation/div-by-zero.c
@@ -0,0 +1,66 @@
+int  scdiv(int a) { return 2 / 0; }
+int iscdiv(int a) { return 2 / (int) 0; }
+int lscdiv(int a) { return 2 / (long) 0; }
+int uscdiv(int a) { return 2 / (unsigned int) 0; }
+
+int  svdiv(int a) { return a / 0; }
+int isvdiv(int a) { return a / (int) 0; }
+int lsvdiv(int a) { return a / (long) 0; }
+int usvdiv(int a) { return a / (unsigned int) 0; }
+
+int  scmod(int a) { return 2 % 0; }
+int iscmod(int a) { return 2 % (int) 0; }
+int lscmod(int a) { return 2 % (long) 0; }
+int uscmod(int a) { return 2 % (unsigned int) 0; }
+
+int  svmod(int a) { return a % 0; }
+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); }
+
+int ysvdiv(int a) { if (a && 0) return a /= 0; return 0; }
+int ysvmod(int a) { if (a && 0) return a %= 0; return 0; }
+
+int zsvdiv(int a) { if (0 && (a /  0)) return 1; return 0; }
+int zsvmod(int a) { if (0 && (a /= 0)) return 1; return 0; }
+
+int wsvdiv(int a) { if (0) return a / 0; return 0; }
+int wsvmod(int a) { if (0) return a % 0; return 0; }
+int vsvdiv(int a) { if (0) return a /= 0; return 0; }
+int vsvmod(int a) { if (0) return a %= 0; return 0; }
+
+/*
+ * check-name: div-by-zero.c
+ * check-command: sparse -Wno-decl $file
+ *
+ * check-error-start
+div-by-zero.c:1:30: warning: division by zero
+div-by-zero.c:2:30: warning: division by zero
+div-by-zero.c:3:30: warning: division by zero
+div-by-zero.c:4:30: warning: division by zero
+div-by-zero.c:6:30: warning: division by zero
+div-by-zero.c:7:30: warning: division by zero
+div-by-zero.c:8:30: warning: division by zero
+div-by-zero.c:9:30: warning: division by zero
+div-by-zero.c:11:30: warning: division by zero
+div-by-zero.c:12:30: warning: division by zero
+div-by-zero.c:13:30: warning: division by zero
+div-by-zero.c:14:30: warning: division by zero
+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:25:42: warning: division by zero
+div-by-zero.c:35:37: warning: division by zero
+div-by-zero.c:36:37: warning: division by zero
+ * check-error-end
+ */
-- 
2.13.0


  parent reply	other threads:[~2017-06-03  8:01 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-03  8:01 [PATCH v2 0/8] division-by-zero warnings Luc Van Oostenryck
2017-06-03  8:01 ` [PATCH v2 1/8] add is_pseudo_value() Luc Van Oostenryck
2017-06-03  8:01 ` [PATCH v2 2/8] add a .warned field to struct instruction Luc Van Oostenryck
2017-06-03  8:01 ` Luc Van Oostenryck [this message]
2017-06-03  8:01 ` [PATCH v2 4/8] div0: also check for compound assignments Luc Van Oostenryck
2017-06-03  8:01 ` [PATCH v2 5/8] div0: add warning option -Wdiv-by-zero Luc Van Oostenryck
2017-06-03  8:01 ` [PATCH v2 6/8] div0: use -Wdiv-by-zero Luc Van Oostenryck
2017-06-03  8:01 ` [PATCH v2 7/8] div0: warn also during simplification Luc Van Oostenryck
2017-06-03  8:01 ` [PATCH v2 8/8] div0: warn on float divide by 0 also when the lhs is not constant Luc Van Oostenryck
2017-06-05 19:16 ` [PATCH v2 0/8] division-by-zero warnings Christopher Li

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=20170603080135.46477-4-luc.vanoostenryck@gmail.com \
    --to=luc.vanoostenryck@gmail.com \
    --cc=linux-sparse@vger.kernel.org \
    --cc=sparse@chrisli.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).