about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Src/math.c26
2 files changed, 29 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index ff8c8f666..a546a3f50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-09-06  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 30656: Src/math.c: treat dividing by -1 the same as
+	multiplying by it to get around SIGFPE.
+
 2012-09-05  Peter Stephenson  <pws@csr.com>
 
 	* Jun T.: 30658: Completion/Unix/Command/_uniq: more options.
@@ -137,5 +142,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5715 $
+* $Revision: 1.5716 $
 *****************************************************
diff --git a/Src/math.c b/Src/math.c
index cca521098..c7d384019 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -1053,14 +1053,34 @@ op(int what)
 		    return;
 		if (c.type == MN_FLOAT)
 		    c.u.d = a.u.d / b.u.d;
-		else
-		    c.u.l = a.u.l / b.u.l;
+		else {
+		    /*
+		     * Avoid exception when dividing the smallest
+		     * negative integer by -1.  Always treat it the
+		     * same as multiplication.  This still doesn't give
+		     * numerically the right answer in two's complement,
+		     * but treating both these in the same way seems
+		     * reasonable.
+		     */
+		    if (b.u.l == -1)
+			c.u.l = - a.u.l;
+		    else
+			c.u.l = a.u.l / b.u.l;
+		}
 		break;
 	    case MOD:
 	    case MODEQ:
 		if (!notzero(b))
 		    return;
-		c.u.l = a.u.l % b.u.l;
+		/*
+		 * Avoid exception as above.
+		 * Any integer mod -1 is the same as any integer mod 1
+		 * i.e. zero.
+		 */
+		if (b.u.l == -1)
+		    c.u.l = 0;
+		else
+		    c.u.l = a.u.l % b.u.l;
 		break;
 	    case PLUS:
 	    case PLUSEQ: