]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix recently-introduced Fdelete bug
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 15 Aug 2020 19:32:56 +0000 (12:32 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 15 Aug 2020 19:37:04 +0000 (12:37 -0700)
Problem reported by Pip Cet in:
https://lists.gnu.org/r/emacs-devel/2020-08/msg00444.html
* src/fns.c (Fdelete): Fix correctness bug via a simpler (though more
memory-intensive) approach.  It’s probably not worth optimizing
the memory usage yere.
* test/src/fns-tests.el (test-vector-delete): Add test for the bug.

src/fns.c
test/src/fns-tests.el

index 069edbe90e28eb243431d837ff8177835939316b..a3b8d6ef57d7f0e6344bcb8ec782bc3ed57e13c5 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -1749,38 +1749,17 @@ changing the value of a sequence `foo'.  */)
     {
       ptrdiff_t n = 0;
       ptrdiff_t size = ASIZE (seq);
-      ptrdiff_t neqbits_words = ((size + BITS_PER_BITS_WORD - 1)
-                                / BITS_PER_BITS_WORD);
       USE_SAFE_ALLOCA;
-      bits_word *neqbits = SAFE_ALLOCA (neqbits_words * sizeof *neqbits);
-      bits_word neqword = 0;
+      Lisp_Object *kept = SAFE_ALLOCA (size * sizeof *kept);
 
       for (ptrdiff_t i = 0; i < size; i++)
        {
-         bool neq = NILP (Fequal (AREF (seq, i), elt));
-         n += neq;
-         neqbits[i / BITS_PER_BITS_WORD] = neqword = (neqword << 1) + neq;
+         kept[n] = AREF (seq, i);
+         n += NILP (Fequal (AREF (seq, i), elt));
        }
 
       if (n != size)
-       {
-         struct Lisp_Vector *p = allocate_vector (n);
-
-         if (n != 0)
-           {
-             ptrdiff_t j = 0;
-             for (ptrdiff_t i = 0; ; i++)
-               if (neqbits[i / BITS_PER_BITS_WORD]
-                   & ((bits_word) 1 << (i % BITS_PER_BITS_WORD)))
-                 {
-                   p->contents[j++] = AREF (seq, i);
-                   if (j == n)
-                     break;
-                 }
-           }
-
-         XSETVECTOR (seq, p);
-       }
+       seq = Fvector (n, kept);
 
       SAFE_FREE ();
     }
index 141de1d226c37b6dabc3afaaeca04880d8096147..400e9126486a42baab35e4bd9229c7930e3b9b12 100644 (file)
 
 (ert-deftest test-vector-delete ()
   (let ((v1 (make-vector 1000 1)))
+    (should (equal (delete t [nil t]) [nil]))
     (should (equal (delete 1 v1) (vector)))
     (should (equal (delete 2 v1) v1))))