https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112889

David Malcolm <dmalcolm at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2023-12-06

--- Comment #1 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
Happens for a concrete_binding 2 bits below the start of the base region, due
to:

172           bool ins = Traits::is_empty (*e);
173           if (ins)
174             {
175               e->m_key = k;
176               new ((void *)&e->m_value) Value (v);
177               gcc_checking_assert (!Traits::is_empty (*e)
178                                    && !Traits::is_deleted (*e));
179             }

(gdb) call b.dump(true)
start: -2, size: 1, next: -1

(gdb) p k.is_empty()
$6 = true
(gdb) p k.is_deleted()
$7 = false

where concrete_binding has:
  void mark_deleted () { m_bit_range.m_start_bit_offset = -1; }
  void mark_empty () { m_bit_range.m_start_bit_offset = -2; }
  bool is_deleted () const { return m_bit_range.m_start_bit_offset == -1; }
  bool is_empty () const { return m_bit_range.m_start_bit_offset == -2; }

Possibly also affects the "1 bit before the base region" case as well.

Working on a fix to use the size field for the deleted/empty values.

It's a failing assertion, so may well be present (but latent) in older
releases.

Reply via email to