Skip to content

Commit

Permalink
Avoid calling overridden virtual method in base class destructor
Browse files Browse the repository at this point in the history
Fixes some undefined behavior when deleting layout items
  • Loading branch information
nyalldawson committed Oct 3, 2023
1 parent a3a0e7b commit 17a34a1
Show file tree
Hide file tree
Showing 8 changed files with 17 additions and 2 deletions.
1 change: 1 addition & 0 deletions python/core/auto_generated/layout/qgslayoutframe.sip.in
Expand Up @@ -27,6 +27,7 @@ Base class for frame items, which form a layout multiframe item.
Constructor for QgsLayoutFrame, with the specified parent ``layout``
and belonging to a ``multiFrame``.
%End
~QgsLayoutFrame();

static QgsLayoutFrame *create( QgsLayout *layout ) /Factory/;
%Docstring
Expand Down
Expand Up @@ -25,6 +25,7 @@ A container for grouping several :py:class:`QgsLayoutItems`.
%Docstring
Constructor for QgsLayoutItemGroup, belonging to the specified ``layout``.
%End
~QgsLayoutItemGroup();

virtual void cleanup();

Expand Down
2 changes: 1 addition & 1 deletion src/core/layout/qgslayout.cpp
Expand Up @@ -318,7 +318,7 @@ QgsLayoutItem *QgsLayout::layoutItemAt( QPointF position, const QgsLayoutItem *b
}

bool foundBelowItem = false;
for ( QGraphicsItem *graphicsItem : itemList )
for ( QGraphicsItem *graphicsItem : std::as_const( itemList ) )
{
QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( graphicsItem );
QgsLayoutItemPage *paperItem = dynamic_cast<QgsLayoutItemPage *>( layoutItem );
Expand Down
6 changes: 6 additions & 0 deletions src/core/layout/qgslayoutframe.cpp
Expand Up @@ -41,6 +41,11 @@ QgsLayoutFrame::QgsLayoutFrame( QgsLayout *layout, QgsLayoutMultiFrame *multiFra
}
}

QgsLayoutFrame::~QgsLayoutFrame()
{
QgsLayoutFrame::cleanup();
}

QgsLayoutFrame *QgsLayoutFrame::create( QgsLayout *layout )
{
return new QgsLayoutFrame( layout, nullptr );
Expand Down Expand Up @@ -158,6 +163,7 @@ void QgsLayoutFrame::cleanup()
{
if ( mMultiFrame )
mMultiFrame->handleFrameRemoval( this );
mMultiFrame = nullptr;

QgsLayoutItem::cleanup();
}
Expand Down
1 change: 1 addition & 0 deletions src/core/layout/qgslayoutframe.h
Expand Up @@ -39,6 +39,7 @@ class CORE_EXPORT QgsLayoutFrame: public QgsLayoutItem
* and belonging to a \a multiFrame.
*/
QgsLayoutFrame( QgsLayout *layout, QgsLayoutMultiFrame *multiFrame );
~QgsLayoutFrame() override;

/**
* Creates a new QgsLayoutFrame belonging to the specified \a layout.
Expand Down
2 changes: 1 addition & 1 deletion src/core/layout/qgslayoutitem.cpp
Expand Up @@ -95,7 +95,7 @@ QgsLayoutItem::QgsLayoutItem( QgsLayout *layout, bool manageZValue )

QgsLayoutItem::~QgsLayoutItem()
{
cleanup();
QgsLayoutItem::cleanup();
}

void QgsLayoutItem::cleanup()
Expand Down
5 changes: 5 additions & 0 deletions src/core/layout/qgslayoutitemgroup.cpp
Expand Up @@ -25,6 +25,11 @@ QgsLayoutItemGroup::QgsLayoutItemGroup( QgsLayout *layout )
: QgsLayoutItem( layout )
{}

QgsLayoutItemGroup::~QgsLayoutItemGroup()
{
QgsLayoutItemGroup::cleanup();
}

void QgsLayoutItemGroup::cleanup()
{
//loop through group members and remove them from the scene
Expand Down
1 change: 1 addition & 0 deletions src/core/layout/qgslayoutitemgroup.h
Expand Up @@ -35,6 +35,7 @@ class CORE_EXPORT QgsLayoutItemGroup: public QgsLayoutItem
* Constructor for QgsLayoutItemGroup, belonging to the specified \a layout.
*/
explicit QgsLayoutItemGroup( QgsLayout *layout );
~QgsLayoutItemGroup() override;

void cleanup() override;

Expand Down

0 comments on commit 17a34a1

Please sign in to comment.