From dff58577d80f6c65b15534cef749f5ff8ccd28ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Mon, 11 Oct 2010 15:14:55 +0200 Subject: [PATCH] Fix a bug in weak hash table bucket fixup. * libguile/hashtab.c (scm_fixup_weak_alist): Keep the value of PREV unchanged after a nullified pair is deleted; this fixes a bug whereby if several successive nullified pairs were encountered, not all of them would be removed, and the assertion in `weak_bucket_assoc' would be hit. In addition, remove the `scm_is_pair (pair)' test. --- libguile/hashtab.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/libguile/hashtab.c b/libguile/hashtab.c index 78a265ded..1609f2203 100644 --- a/libguile/hashtab.c +++ b/libguile/hashtab.c @@ -102,25 +102,25 @@ scm_fixup_weak_alist (SCM alist, size_t *removed_items) *removed_items = 0; for (result = alist; scm_is_pair (alist); - prev = alist, alist = SCM_CDR (alist)) + alist = SCM_CDR (alist)) { SCM pair = SCM_CAR (alist); - if (scm_is_pair (pair)) + if (SCM_WEAK_PAIR_DELETED_P (pair)) { - if (SCM_WEAK_PAIR_DELETED_P (pair)) - { - /* Remove from ALIST weak pair PAIR whose car/cdr has been - nullified by the GC. */ - if (prev == SCM_EOL) - result = SCM_CDR (alist); - else - SCM_SETCDR (prev, SCM_CDR (alist)); + /* Remove from ALIST weak pair PAIR whose car/cdr has been + nullified by the GC. */ + if (prev == SCM_EOL) + result = SCM_CDR (alist); + else + SCM_SETCDR (prev, SCM_CDR (alist)); - (*removed_items)++; - continue; - } + (*removed_items)++; + + /* Leave PREV unchanged. */ } + else + prev = alist; } return result;