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

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
We for example have

  tem_23->hasFinalizer_ = 1;
...
  MEM[(struct Object *)interp_8(D) + 16B].next_ = tem_23;
  MEM[(struct  &)tem_23] ={v} {CLOBBER};

which means that tem_23 escapes through memory pointed to by a paramter but
is marked as lifetime ended.

This looks like it is because the new expression in

DEFPRIMITIVE(CurrentNodePageNumberSosofo, argc, argv, context, interp, loc)
{
  if (!context.currentNode)
    return noCurrentNodeError(interp, loc);
  return new (interp) CurrentNodePageNumberSosofoObj(context.currentNode);
}

ends up generating


;; Function
OpenJade_DSSSL::CurrentNodePageNumberSosofoObj::CurrentNodePageNumberSosofoObj(const
OpenJade_Grove::NodePtr&) (null)
;; enabled by -tree-original

<<cleanup_point <<< Unknown tree: expr_stmt
  (void) (*(struct
  {
    struct
    {
      struct
      {
        struct
        {
          int (*__vtbl_ptr_type) () * _vptr.Object;
          struct Object * prev_;
          struct Object * next_;
          char color_;
          char hasFinalizer_;
          char hasSubObjects_;
          char readOnly_;
        } D.16565;
      } D.31225;
    } D.31630;
    struct NodePtr node_;
  } &) this = {CLOBBER}) >>>>>;
{
  <<cleanup_point <<< Unknown tree: expr_stmt
  OpenJade_DSSSL::SosofoObj::SosofoObj (&((struct
CurrentNodePageNumberSosofoObj *) this)->D.31629) >>>>>;
  try
    {
      <<cleanup_point <<< Unknown 
...

and thus first clobbering the memory state of the object!  That of course
interferes with the allocator GCC sees.

Remember those objects have new operators that first call

inline
void *Collector::allocateObject(bool hasFinalizer)
{
  if (freePtr_ == &allObjectsList_)
    makeSpace();
  Object *tem = freePtr_;
  freePtr_ = freePtr_->next();
  tem->setColor(currentColor_);
  tem->hasFinalizer_ = hasFinalizer;
  if (hasFinalizer)
    tem->moveAfter(&allObjectsList_);
  return tem;
}

Reply via email to