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; }