From 748afc183c2c44b7b2a582d3078cf3d8b4d5270a Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 15 Aug 2020 12:32:56 -0700 Subject: [PATCH] Fix recently-introduced Fdelete bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 29 ++++------------------------- test/src/fns-tests.el | 1 + 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/fns.c b/src/fns.c index 069edbe90e..a3b8d6ef57 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1749,38 +1749,17 @@ DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0, { 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 (); } diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index 141de1d226..400e912648 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el @@ -898,5 +898,6 @@ test-secure-hash (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)))) -- 2.17.1