The following guards against (some) remove-current-bit cases. It would have ICEd for PR77855 instead of producing wrong code.
Bootstrap / regtest running on x86_64-unknown-linux-gnu. Comments? Thanks, Richard. 2016-10-06 Richard Biener <rguent...@suse.de> * bitmap.c (bitmap_elem_to_freelist): Set indx to -1. * bitmap.h (bmp_iter_set): When advancing to the next element check that we didn't remove the current one. (bmp_iter_and): Likewise. (bmp_iter_and_compl): Likewise. Index: gcc/bitmap.c =================================================================== --- gcc/bitmap.c (revision 240828) +++ gcc/bitmap.c (working copy) @@ -66,6 +66,7 @@ bitmap_elem_to_freelist (bitmap head, bi bitmap_obstack *bit_obstack = head->obstack; elt->next = NULL; + elt->indx = -1; if (bit_obstack) { elt->prev = bit_obstack->elements; Index: gcc/bitmap.h =================================================================== --- gcc/bitmap.h (revision 240828) +++ gcc/bitmap.h (working copy) @@ -618,6 +618,9 @@ bmp_iter_set (bitmap_iterator *bi, unsig bi->word_no++; } + /* Make sure we didn't remove the element while iterating. */ + gcc_checking_assert (bi->elt1->indx != -1); + /* Advance to the next element. */ bi->elt1 = bi->elt1->next; if (!bi->elt1) @@ -664,6 +667,9 @@ bmp_iter_and (bitmap_iterator *bi, unsig /* Advance to the next identical element. */ do { + /* Make sure we didn't remove the element while iterating. */ + gcc_checking_assert (bi->elt1->indx != -1); + /* Advance elt1 while it is less than elt2. We always want to advance one elt. */ do @@ -674,6 +680,9 @@ bmp_iter_and (bitmap_iterator *bi, unsig } while (bi->elt1->indx < bi->elt2->indx); + /* Make sure we didn't remove the element while iterating. */ + gcc_checking_assert (bi->elt2->indx != -1); + /* Advance elt2 to be no less than elt1. This might not advance. */ while (bi->elt2->indx < bi->elt1->indx) @@ -726,11 +735,17 @@ bmp_iter_and_compl (bitmap_iterator *bi, bi->word_no++; } + /* Make sure we didn't remove the element while iterating. */ + gcc_checking_assert (bi->elt1->indx != -1); + /* Advance to the next element of elt1. */ bi->elt1 = bi->elt1->next; if (!bi->elt1) return false; + /* Make sure we didn't remove the element while iterating. */ + gcc_checking_assert (bi->elt2->indx != -1); + /* Advance elt2 until it is no less than elt1. */ while (bi->elt2 && bi->elt2->indx < bi->elt1->indx) bi->elt2 = bi->elt2->next;