diff options
| author | Paul Eggert | 2020-01-07 11:23:11 -0800 |
|---|---|---|
| committer | Paul Eggert | 2020-01-07 11:29:42 -0800 |
| commit | 724af7671590cd91df37f64df6be73f6dca0144d (patch) | |
| tree | 075df63dcdc3653ff710ce49a5f238c165d0f0c1 /src/fns.c | |
| parent | f950b078a6f2fd011312e9471998edf6b5fb957e (diff) | |
| download | emacs-724af7671590cd91df37f64df6be73f6dca0144d.tar.gz emacs-724af7671590cd91df37f64df6be73f6dca0144d.zip | |
Fix sxhash-equal on bytecodes, markers, etc.
Problem reported by Pip Cet (Bug#38912#14).
* doc/lispref/objects.texi (Equality Predicates):
Document better when ‘equal’ looks inside objects.
* doc/lispref/windows.texi (Window Configurations):
Don’t say that ‘equal’ looks inside window configurations.
* etc/NEWS: Mention the change.
* src/fns.c (internal_equal):
Do not look inside window configurations.
(sxhash_obj): Hash markers, byte-code function objects,
char-tables, and font objects consistently with Fequal.
* src/window.c (compare_window_configurations):
Now static. Remove last argument. Caller changed.
* test/lisp/ffap-tests.el (ffap-other-window--bug-25352):
Use compare-window-configurations, not ‘equal’.
* test/src/fns-tests.el (test-sxhash-equal): New test.
Diffstat (limited to 'src/fns.c')
| -rw-r--r-- | src/fns.c | 52 |
1 files changed, 31 insertions, 21 deletions
| @@ -2434,6 +2434,9 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2434 | same size. */ | 2434 | same size. */ |
| 2435 | if (ASIZE (o2) != size) | 2435 | if (ASIZE (o2) != size) |
| 2436 | return false; | 2436 | return false; |
| 2437 | |||
| 2438 | /* Compare bignums, overlays, markers, and boolvectors | ||
| 2439 | specially, by comparing their values. */ | ||
| 2437 | if (BIGNUMP (o1)) | 2440 | if (BIGNUMP (o1)) |
| 2438 | return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0; | 2441 | return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0; |
| 2439 | if (OVERLAYP (o1)) | 2442 | if (OVERLAYP (o1)) |
| @@ -2454,7 +2457,6 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2454 | && (XMARKER (o1)->buffer == 0 | 2457 | && (XMARKER (o1)->buffer == 0 |
| 2455 | || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos)); | 2458 | || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos)); |
| 2456 | } | 2459 | } |
| 2457 | /* Boolvectors are compared much like strings. */ | ||
| 2458 | if (BOOL_VECTOR_P (o1)) | 2460 | if (BOOL_VECTOR_P (o1)) |
| 2459 | { | 2461 | { |
| 2460 | EMACS_INT size = bool_vector_size (o1); | 2462 | EMACS_INT size = bool_vector_size (o1); |
| @@ -2465,11 +2467,6 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2465 | return false; | 2467 | return false; |
| 2466 | return true; | 2468 | return true; |
| 2467 | } | 2469 | } |
| 2468 | if (WINDOW_CONFIGURATIONP (o1)) | ||
| 2469 | { | ||
| 2470 | eassert (equal_kind != EQUAL_NO_QUIT); | ||
| 2471 | return compare_window_configurations (o1, o2, false); | ||
| 2472 | } | ||
| 2473 | 2470 | ||
| 2474 | /* Aside from them, only true vectors, char-tables, compiled | 2471 | /* Aside from them, only true vectors, char-tables, compiled |
| 2475 | functions, and fonts (font-spec, font-entity, font-object) | 2472 | functions, and fonts (font-spec, font-entity, font-object) |
| @@ -4703,22 +4700,35 @@ sxhash_obj (Lisp_Object obj, int depth) | |||
| 4703 | hash = sxhash_string (SSDATA (obj), SBYTES (obj)); | 4700 | hash = sxhash_string (SSDATA (obj), SBYTES (obj)); |
| 4704 | break; | 4701 | break; |
| 4705 | 4702 | ||
| 4706 | /* This can be everything from a vector to an overlay. */ | ||
| 4707 | case Lisp_Vectorlike: | 4703 | case Lisp_Vectorlike: |
| 4708 | if (BIGNUMP (obj)) | 4704 | { |
| 4709 | hash = sxhash_bignum (obj); | 4705 | enum pvec_type pvec_type = PSEUDOVECTOR_TYPE (XVECTOR (obj)); |
| 4710 | else if (VECTORP (obj) || RECORDP (obj)) | 4706 | if (! (PVEC_NORMAL_VECTOR < pvec_type && pvec_type < PVEC_COMPILED)) |
| 4711 | /* According to the CL HyperSpec, two arrays are equal only if | 4707 | { |
| 4712 | they are `eq', except for strings and bit-vectors. In | 4708 | /* According to the CL HyperSpec, two arrays are equal only if |
| 4713 | Emacs, this works differently. We have to compare element | 4709 | they are 'eq', except for strings and bit-vectors. In |
| 4714 | by element. Same for records. */ | 4710 | Emacs, this works differently. We have to compare element |
| 4715 | hash = sxhash_vector (obj, depth); | 4711 | by element. Same for pseudovectors that internal_equal |
| 4716 | else if (BOOL_VECTOR_P (obj)) | 4712 | examines the Lisp contents of. */ |
| 4717 | hash = sxhash_bool_vector (obj); | 4713 | hash = sxhash_vector (obj, depth); |
| 4718 | else | 4714 | break; |
| 4719 | /* Others are `equal' if they are `eq', so let's take their | 4715 | } |
| 4720 | address as hash. */ | 4716 | else if (pvec_type == PVEC_BIGNUM) |
| 4721 | hash = XHASH (obj); | 4717 | hash = sxhash_bignum (obj); |
| 4718 | else if (pvec_type == PVEC_MARKER) | ||
| 4719 | { | ||
| 4720 | ptrdiff_t bytepos | ||
| 4721 | = XMARKER (obj)->buffer ? XMARKER (obj)->bytepos : 0; | ||
| 4722 | hash = sxhash_combine ((intptr_t) XMARKER (obj)->buffer, bytepos); | ||
| 4723 | hash = SXHASH_REDUCE (hash); | ||
| 4724 | } | ||
| 4725 | else if (pvec_type == PVEC_BOOL_VECTOR) | ||
| 4726 | hash = sxhash_bool_vector (obj); | ||
| 4727 | else | ||
| 4728 | /* Others are 'equal' if they are 'eq', so take their | ||
| 4729 | address as hash. */ | ||
| 4730 | hash = XHASH (obj); | ||
| 4731 | } | ||
| 4722 | break; | 4732 | break; |
| 4723 | 4733 | ||
| 4724 | case Lisp_Cons: | 4734 | case Lisp_Cons: |