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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|-fmem-stats tracking of     |-fmem-stats tracking of
                   |vec<> does not track        |vec<> does not follow vec<>
                   |::release                   |assignments
   Last reconfirmed|                            |2026-03-18
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ah, I think it is

  vr1->operands = operands.copy ();

not being properly tracked.  We do

/* Return a pointer to a copy of this vector.  */

template<typename T, typename A>
inline vec<T, A, vl_embed> *
vec<T, A, vl_embed>::copy (ALONE_MEM_STAT_DECL) const
{                                 
  vec<T, A, vl_embed> *new_vec = NULL;
  unsigned len = length ();
  if (len)
    {
      vec_alloc (new_vec, len PASS_MEM_STAT);
      new_vec->embedded_init (len, len);
      vec_copy_construct (new_vec->address (), address (), len);
    }
  return new_vec;

and there's no move operator that would move the storage association with
the memory statistic machinery (or in general).  The copy () API isn't
particularly well-designed in this regard (and thus also error-prone to
use).  It might be tempting to use an auto_vec<> return value.

That said, instead of the above vr1->operands = operands.copy ();
one could use

   vr1->operands = vNULL;
   vr1->operands.safe_splice (operands);

which is accounted correctly.  A vr1->operands.copy_from (other) might
also work, but it also requires initialization of vr1->operands.

::copy () is also used for parameter passing,
so this isn't an universal solution.  Having auto_vec<> parameters for
functions owning such reference would work, but the involved CTOR also
doesn't accout statistics correctly:

  auto_vec (vec<T, va_heap>&& r)
    {
      gcc_assert (!r.using_auto_storage ());
      this->m_vec = r.m_vec;
      r.m_vec = NULL;
    }

but we likely cannot add a PASS_MEM_STATS to CTORs(?).

Like in vn_reference_lookup_or_insert_for_pieces we do

  return vn_reference_insert_pieces (vuse, set, base_set, offset, max_size,
                                     type, operands.copy (), value, value_id);

which in turn does

  vr1->operands = operands;

in combination this will work for statistics gathering, using auto_vec<>
would break it (and require to_vec_legacy, ugh).

Reply via email to