Subject: Re: bug#32463: 27.0.50; (logior -1) => 4611686018427387903

From: Pip Cet <[email-masked]>
Date: Fri, 17 Aug 2018 11:53:45 +0000

On Fri, Aug 17, 2018 at 11:36 AM Pip Cet <[email-masked]> wrote:
> and got this output:

I forgot to mention this is on an x86-64 machine with a Linux kernel
and Debian GNU/Linux, and external libgmp.

I'm attaching the patch that I think should still be applied, which
includes some tests.
diff --git a/src/data.c b/src/data.c
index 5a355d9787c..077cc8283eb 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3382,8 +3382,6 @@ ash_lsh_impl (Lisp_Object value, Lisp_Object count, bool lsh)
       mpz_init (result);
       if (XFIXNUM (count) >= 0)
 	mpz_mul_2exp (result, XBIGNUM (value)->value, XFIXNUM (count));
-      else if (lsh)
-	mpz_tdiv_q_2exp (result, XBIGNUM (value)->value, - XFIXNUM (count));
       else
 	mpz_fdiv_q_2exp (result, XBIGNUM (value)->value, - XFIXNUM (count));
       val = make_number (result);
@@ -3400,14 +3398,7 @@ ash_lsh_impl (Lisp_Object value, Lisp_Object count, bool lsh)
 
       if (XFIXNUM (count) >= 0)
 	mpz_mul_2exp (result, result, XFIXNUM (count));
-      else if (lsh)
-	{
-	  if (mpz_sgn (result) > 0)
-	    mpz_fdiv_q_2exp (result, result, - XFIXNUM (count));
-	  else
-	    mpz_fdiv_q_2exp (result, result, - XFIXNUM (count));
-	}
-      else /* ash */
+      else
 	mpz_fdiv_q_2exp (result, result, - XFIXNUM (count));
 
       val = make_number (result);
diff --git a/src/fns.c b/src/fns.c
index f6e68036413..5f4b455b503 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -56,15 +56,15 @@ DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
 }
 
 DEFUN ("random", Frandom, Srandom, 0, 1, 0,
-       doc: /* Return a pseudo-random number.
-All integers representable in Lisp, i.e. between `most-negative-fixnum'
+       doc: /* Return a pseudo-random fixnum.
+All integers representable as fixnums, i.e. between `most-negative-fixnum'
 and `most-positive-fixnum', inclusive, are equally likely.
 
-With positive integer LIMIT, return random number in interval [0,LIMIT).
-With argument t, set the random number seed from the system's entropy
-pool if available, otherwise from less-random volatile data such as the time.
-With a string argument, set the seed based on the string's contents.
-Other values of LIMIT are ignored.
+With positive fixnum integer LIMIT, return random number in interval
+[0,LIMIT).  With argument t, set the random number seed from the
+system's entropy pool if available, otherwise from less-random
+volatile data such as the time.  With a string argument, set the seed
+based on the string's contents.  Other values of LIMIT are ignored.
 
 See Info node `(elisp)Random Numbers' for more details.  */)
   (Lisp_Object limit)
diff --git a/test/src/data-tests.el b/test/src/data-tests.el
index a4c6b0e4915..6a2578e19a0 100644
--- a/test/src/data-tests.el
+++ b/test/src/data-tests.el
@@ -614,6 +614,11 @@ binding-test-some-local
   (let ((n (1+ most-positive-fixnum)))
     (should (= (logxor -1 n) (lognot n)))))
 
+(ert-deftest data-tests-logand ()
+  (should (= -1 (logand) (logand -1) (logand -1 -1)))
+  (let ((n (1+ most-positive-fixnum)))
+    (should (= (logand -1 n) n))))
+
 (ert-deftest data-tests-minmax ()
   (let ((a (- most-negative-fixnum 1))
         (b (+ most-positive-fixnum 1))
@@ -642,6 +647,14 @@ data-tests-check-sign
   (should (= (ash most-negative-fixnum 1)
              (* most-negative-fixnum 2)))
   (should (= (lsh most-negative-fixnum 1)
-             (* most-negative-fixnum 2))))
+             (* most-negative-fixnum 2)))
+  (should (= (ash (* 2 most-negative-fixnum) -1)
+             most-negative-fixnum))
+  (should (= (lsh (* 2 most-negative-fixnum) -1)
+             most-negative-fixnum))
+  (should (= (lsh (- (lsh most-negative-fixnum 1) 1) -1)
+             (- most-negative-fixnum 1)))
+  (should (= (ash (- (lsh most-negative-fixnum 1) 1) -1)
+             (- most-negative-fixnum 1))))
 
 ;;; data-tests.el ends here