aboutsummaryrefslogtreecommitdiffstats
path: root/src/fns.c
diff options
context:
space:
mode:
authorPaul Eggert2020-01-07 11:23:11 -0800
committerPaul Eggert2020-01-07 11:29:42 -0800
commit724af7671590cd91df37f64df6be73f6dca0144d (patch)
tree075df63dcdc3653ff710ce49a5f238c165d0f0c1 /src/fns.c
parentf950b078a6f2fd011312e9471998edf6b5fb957e (diff)
downloademacs-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.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/src/fns.c b/src/fns.c
index 4a0a8fd96d8..4a463a8feb2 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -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: