aboutsummaryrefslogtreecommitdiffstats
path: root/src/fns.c
diff options
context:
space:
mode:
authorPaul Eggert2019-08-21 00:06:00 -0700
committerPaul Eggert2019-08-21 00:11:45 -0700
commit39fee209942ab7c35b4789f0010264cd6a52197b (patch)
tree96f1858c890436713ba0da0fca93d1f33d7dd33a /src/fns.c
parent3881542edeac3e94291c2ce574edf0b0e52764a8 (diff)
downloademacs-39fee209942ab7c35b4789f0010264cd6a52197b.tar.gz
emacs-39fee209942ab7c35b4789f0010264cd6a52197b.zip
Be more careful about pointers to bignum vals
This uses ‘const’ to be better at catching bugs that mistakenly attempt to modify a bignum value. Lisp bignums are supposed to be immutable. * src/alloc.c (make_pure_bignum): * src/fns.c (sxhash_bignum): Accept Lisp_Object instead of struct Lisp_Bignum *, as that’s simpler now. Caller changed. * src/bignum.h (bignum_val, xbignum_val): New inline functions. Prefer them to &i->value and XBIGNUM (i)->value, since they apply ‘const’ to the result. * src/timefns.c (lisp_to_timespec): Use mpz_t const * to point to a bignum value.
Diffstat (limited to 'src/fns.c')
-rw-r--r--src/fns.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/src/fns.c b/src/fns.c
index 920addeaf13..6c47b3e5b1c 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -47,7 +47,6 @@ static void sort_vector_copy (Lisp_Object, ptrdiff_t,
47enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; 47enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES };
48static bool internal_equal (Lisp_Object, Lisp_Object, 48static bool internal_equal (Lisp_Object, Lisp_Object,
49 enum equal_kind, int, Lisp_Object); 49 enum equal_kind, int, Lisp_Object);
50static EMACS_UINT sxhash_bignum (struct Lisp_Bignum *);
51 50
52DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, 51DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
53 doc: /* Return the argument unchanged. */ 52 doc: /* Return the argument unchanged. */
@@ -1444,7 +1443,7 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
1444 } 1443 }
1445 else 1444 else
1446 { 1445 {
1447 if (mpz_sgn (XBIGNUM (n)->value) < 0) 1446 if (mpz_sgn (*xbignum_val (n)) < 0)
1448 return tail; 1447 return tail;
1449 num = large_num; 1448 num = large_num;
1450 } 1449 }
@@ -1482,11 +1481,11 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
1482 CYCLE_LENGTH. */ 1481 CYCLE_LENGTH. */
1483 /* Add N mod CYCLE_LENGTH to NUM. */ 1482 /* Add N mod CYCLE_LENGTH to NUM. */
1484 if (cycle_length <= ULONG_MAX) 1483 if (cycle_length <= ULONG_MAX)
1485 num += mpz_tdiv_ui (XBIGNUM (n)->value, cycle_length); 1484 num += mpz_tdiv_ui (*xbignum_val (n), cycle_length);
1486 else 1485 else
1487 { 1486 {
1488 mpz_set_intmax (mpz[0], cycle_length); 1487 mpz_set_intmax (mpz[0], cycle_length);
1489 mpz_tdiv_r (mpz[0], XBIGNUM (n)->value, mpz[0]); 1488 mpz_tdiv_r (mpz[0], *xbignum_val (n), mpz[0]);
1490 intptr_t iz; 1489 intptr_t iz;
1491 mpz_export (&iz, NULL, -1, sizeof iz, 0, 0, mpz[0]); 1490 mpz_export (&iz, NULL, -1, sizeof iz, 0, 0, mpz[0]);
1492 num += iz; 1491 num += iz;
@@ -1595,7 +1594,7 @@ The value is actually the tail of LIST whose car is ELT. */)
1595 { 1594 {
1596 Lisp_Object tem = XCAR (tail); 1595 Lisp_Object tem = XCAR (tail);
1597 if (BIGNUMP (tem) 1596 if (BIGNUMP (tem)
1598 && mpz_cmp (XBIGNUM (elt)->value, XBIGNUM (tem)->value) == 0) 1597 && mpz_cmp (*xbignum_val (elt), *xbignum_val (tem)) == 0)
1599 return tail; 1598 return tail;
1600 } 1599 }
1601 } 1600 }
@@ -2307,7 +2306,7 @@ This differs from numeric comparison: (eql 0.0 -0.0) returns nil and
2307 return FLOATP (obj2) && same_float (obj1, obj2) ? Qt : Qnil; 2306 return FLOATP (obj2) && same_float (obj1, obj2) ? Qt : Qnil;
2308 else if (BIGNUMP (obj1)) 2307 else if (BIGNUMP (obj1))
2309 return ((BIGNUMP (obj2) 2308 return ((BIGNUMP (obj2)
2310 && mpz_cmp (XBIGNUM (obj1)->value, XBIGNUM (obj2)->value) == 0) 2309 && mpz_cmp (*xbignum_val (obj1), *xbignum_val (obj2)) == 0)
2311 ? Qt : Qnil); 2310 ? Qt : Qnil);
2312 else 2311 else
2313 return EQ (obj1, obj2) ? Qt : Qnil; 2312 return EQ (obj1, obj2) ? Qt : Qnil;
@@ -2437,7 +2436,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind,
2437 if (ASIZE (o2) != size) 2436 if (ASIZE (o2) != size)
2438 return false; 2437 return false;
2439 if (BIGNUMP (o1)) 2438 if (BIGNUMP (o1))
2440 return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0; 2439 return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0;
2441 if (OVERLAYP (o1)) 2440 if (OVERLAYP (o1))
2442 { 2441 {
2443 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2), 2442 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
@@ -4640,13 +4639,14 @@ sxhash_bool_vector (Lisp_Object vec)
4640/* Return a hash for a bignum. */ 4639/* Return a hash for a bignum. */
4641 4640
4642static EMACS_UINT 4641static EMACS_UINT
4643sxhash_bignum (struct Lisp_Bignum *bignum) 4642sxhash_bignum (Lisp_Object bignum)
4644{ 4643{
4645 size_t i, nlimbs = mpz_size (bignum->value); 4644 mpz_t const *n = xbignum_val (bignum);
4645 size_t i, nlimbs = mpz_size (*n);
4646 EMACS_UINT hash = 0; 4646 EMACS_UINT hash = 0;
4647 4647
4648 for (i = 0; i < nlimbs; ++i) 4648 for (i = 0; i < nlimbs; ++i)
4649 hash = sxhash_combine (hash, mpz_getlimbn (bignum->value, i)); 4649 hash = sxhash_combine (hash, mpz_getlimbn (*n, i));
4650 4650
4651 return SXHASH_REDUCE (hash); 4651 return SXHASH_REDUCE (hash);
4652} 4652}
@@ -4680,7 +4680,7 @@ sxhash (Lisp_Object obj, int depth)
4680 /* This can be everything from a vector to an overlay. */ 4680 /* This can be everything from a vector to an overlay. */
4681 case Lisp_Vectorlike: 4681 case Lisp_Vectorlike:
4682 if (BIGNUMP (obj)) 4682 if (BIGNUMP (obj))
4683 hash = sxhash_bignum (XBIGNUM (obj)); 4683 hash = sxhash_bignum (obj);
4684 else if (VECTORP (obj) || RECORDP (obj)) 4684 else if (VECTORP (obj) || RECORDP (obj))
4685 /* According to the CL HyperSpec, two arrays are equal only if 4685 /* According to the CL HyperSpec, two arrays are equal only if
4686 they are `eq', except for strings and bit-vectors. In 4686 they are `eq', except for strings and bit-vectors. In