Fix recently-introduced Fdelete bug
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.
This commit is contained in:
parent
b467bb531e
commit
748afc183c
2 changed files with 5 additions and 25 deletions
29
src/fns.c
29
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 ();
|
||||
}
|
||||
|
|
|
@ -898,5 +898,6 @@
|
|||
|
||||
(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))))
|
||||
|
|
Loading…
Add table
Reference in a new issue