diff options
| author | Paul Eggert | 2019-08-21 00:06:00 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-08-21 00:11:45 -0700 |
| commit | 39fee209942ab7c35b4789f0010264cd6a52197b (patch) | |
| tree | 96f1858c890436713ba0da0fca93d1f33d7dd33a /src/fns.c | |
| parent | 3881542edeac3e94291c2ce574edf0b0e52764a8 (diff) | |
| download | emacs-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.c | 22 |
1 files changed, 11 insertions, 11 deletions
| @@ -47,7 +47,6 @@ static void sort_vector_copy (Lisp_Object, ptrdiff_t, | |||
| 47 | enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; | 47 | enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; |
| 48 | static bool internal_equal (Lisp_Object, Lisp_Object, | 48 | static bool internal_equal (Lisp_Object, Lisp_Object, |
| 49 | enum equal_kind, int, Lisp_Object); | 49 | enum equal_kind, int, Lisp_Object); |
| 50 | static EMACS_UINT sxhash_bignum (struct Lisp_Bignum *); | ||
| 51 | 50 | ||
| 52 | DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, | 51 | DEFUN ("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 | ||
| 4642 | static EMACS_UINT | 4641 | static EMACS_UINT |
| 4643 | sxhash_bignum (struct Lisp_Bignum *bignum) | 4642 | sxhash_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 |