Oswald Buddenhagen <oswald.buddenhagen@xxxxxx> writes: > if (rearranged) { > + ALLOC_ARRAY(items, todo_list->nr); > + > for (i = 0; i < todo_list->nr; i++) { > enum todo_command command = todo_list->items[i].command; > int cur = i; > @@ -6357,16 +6359,15 @@ int todo_list_rearrange_squash(struct todo_list *todo_list) > continue; > > while (cur >= 0) { > - ALLOC_GROW(items, nr + 1, alloc); > items[nr++] = todo_list->items[cur]; > cur = next[cur]; > } > } > > + assert(nr == todo_list->nr); The assert() made me wonder what kind of bugs we are worried about. The next[] array elements are initialized to -1 and then gets "i" that runs (0..todo_list->nr) and get shuffled among the elements of the same array, so next[cur] reference in the while loop we see above will always be within (0..todo_list->nr). It is trivial to see that the items[] array that is preallocated so that it can hold up to todo_list->nr items is large enough. But the condition of the assert() is even stronger. We want to make sure we did not drop any original items in the todo_list, as the objective of this helper function is to shuffle the insns and selectively turn "pick 01234567 fixup! title of another commit" into "fixup 01234567 fixup! title of another commit". There is no reason we should have fewer elements in the result. All makes sense. Nice. Thanks, will queue. > + todo_list->alloc = nr; > FREE_AND_NULL(todo_list->items); > todo_list->items = items; > - todo_list->nr = nr; > - todo_list->alloc = alloc; > } > > free(next);