https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80721
--- Comment #2 from Markus Eisenmann <meisenmann....@fh-salzburg.ac.at> --- Hi! (In reply to Richard Biener from comment #1) > Confirmed. Isn't it enough to add, after > > else if (reinterpret_cast <char *> (e) + sz > == reinterpret_cast <char *> (first_free_entry)) > { > ... > > a > > else if (reinterpret_cast <char *> (e) > < reinterpret_cast <char *> (first_free_entry)) > { > // First is right of us, replace the head. > free_entry *f = reinterpret_cast <free_entry *> (e); > new (f) free_entry; > f->next = first_free_entry; > first_free_entry = f; > } > > ? That's a much less intrusive (and hard to review) fix. Okay, a less intrusive fix for issue a) [set in front, if free-list is empty or starts with a non merge-able block on a higher address] Instead of (sorry, not fully formatted as unified diff), my suggestion would: allocated_entry *e = reinterpret_cast <allocated_entry *> (reinterpret_cast <char *> (data) - offsetof (allocated_entry, data)); std::size_t sz = e->size; - if (!first_free_entry) + if (!first_free_entry + || (reinterpret_cast <char *> (e) + sz + < reinterpret_cast <char *> (first_free_entry))) { // If the free list is empty just put the entry there. free_entry *f = reinterpret_cast <free_entry *> (e); new (f) free_entry; f->size = sz; - f->next = NULL; + f->next = first_free_entry; first_free_entry = f; } else if (reinterpret_cast <char *> (e) + sz I.e., set in front if first_free_entry = null or has to be first, because non merge-able and a "right" item. Note: Following Merging with head will be "is-as-is"; About issue b) - additional merging with direct right follower - I have to think a little about ... Best regards, Markus