summaryrefslogtreecommitdiffstats
path: root/src/corelib/animation/qanimationgroup.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-14 12:37:40 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-23 16:15:00 +0200
commit48b707224efaa54b4dfd831cfd8fbe9006f99588 (patch)
tree7cdefb068ef609ba1252d5bca0e5f4aabc5f7bfe /src/corelib/animation/qanimationgroup.cpp
parentcf7d990a486b406d558e3291247d4323a9f48c73 (diff)
Fix invalid vptr during destruction of animations
Fixes UBSAN warnings about objects used after partial destruction. Change-Id: Iceea083a77d47335ef595c0ff97b87f35f42e56f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/corelib/animation/qanimationgroup.cpp')
-rw-r--r--src/corelib/animation/qanimationgroup.cpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp
index f47d99eb68..ed40817222 100644
--- a/src/corelib/animation/qanimationgroup.cpp
+++ b/src/corelib/animation/qanimationgroup.cpp
@@ -113,6 +113,11 @@ QAnimationGroup::QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent)
*/
QAnimationGroup::~QAnimationGroup()
{
+ Q_D(QAnimationGroup);
+ // We need to clear the animations now while we are still a valid QAnimationGroup.
+ // If we wait until ~QObject() the QAbstractAnimation's pointer back to us would
+ // point to a QObject, not a valid QAnimationGroup.
+ d->clear(true);
}
/*!
@@ -256,7 +261,7 @@ QAbstractAnimation *QAnimationGroup::takeAnimation(int index)
void QAnimationGroup::clear()
{
Q_D(QAnimationGroup);
- qDeleteAll(d->animations);
+ d->clear(false);
}
/*!
@@ -284,6 +289,24 @@ bool QAnimationGroup::event(QEvent *event)
return QAbstractAnimation::event(event);
}
+void QAnimationGroupPrivate::clear(bool onDestruction)
+{
+ const QList<QAbstractAnimation *> animationsCopy = animations; // taking a copy
+ animations.clear();
+ // Clearing backwards so the indices doesn't change while we remove animations.
+ for (int i = animationsCopy.count() - 1; i >= 0; --i) {
+ QAbstractAnimation *animation = animationsCopy.at(i);
+ animation->setParent(nullptr);
+ QAbstractAnimationPrivate::get(animation)->group = nullptr;
+ // If we are in ~QAnimationGroup() it is not safe to called the virtual
+ // animationRemoved method, which can still be a method in a
+ // QAnimationGroupPrivate derived class that assumes q_ptr is still
+ // a valid derived class of QAnimationGroup.
+ if (!onDestruction)
+ animationRemoved(i, animation);
+ delete animation;
+ }
+}
void QAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *)
{