Q_APPLICATION_STATIC: add missing std::launder()
Unlike Q_GLOBAL_STATIC, a Q_APPLICATION_STATIC can be destroyed and re-created multiple times (if QCoreApplication is, too). This means we're basically in the std::optional case and require std::launder() to avoid UB when the payload type has either of the following: - a const member - a reference member - a vtable and different derived classes might be occupying the same space at different times While we can probably exclude the latter, because we always construct the same type, PlainType, in the storage, the first two can easily happen. Fix by adding the missing std::launder(). As a drive-by, remove the uneeded casting (and now launder()ing) of &storage when passing to innerFunction(), which anyway takes its argument as void*. Amends 81a31beeb25eaf14d5c5f42fe26aa49d6ef29bf8, which changed Q_APPLICATION_STATIC to use inline aligned_union storage instead of the original implementation's unique_ptr. Change-Id: I065bd33812a40195109bf11d5bc79975f2f87cd5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit c53fdcb5ee15c309ba68717fa6564dc1ff4b8618) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
02a03f28f5
commit
bb35230991
@ -9,6 +9,8 @@
|
|||||||
#include <QtCore/qcoreapplication.h>
|
#include <QtCore/qcoreapplication.h>
|
||||||
#include <QtCore/qglobalstatic.h>
|
#include <QtCore/qglobalstatic.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
namespace QtGlobalStatic {
|
namespace QtGlobalStatic {
|
||||||
@ -36,7 +38,7 @@ template <typename QAS> struct ApplicationHolder
|
|||||||
|
|
||||||
static PlainType *realPointer()
|
static PlainType *realPointer()
|
||||||
{
|
{
|
||||||
return reinterpret_cast<PlainType *>(&storage);
|
return std::launder(reinterpret_cast<PlainType *>(&storage));
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from QGlobalStatic::instance()
|
// called from QGlobalStatic::instance()
|
||||||
@ -46,7 +48,7 @@ template <typename QAS> struct ApplicationHolder
|
|||||||
return realPointer();
|
return realPointer();
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
if (guard.loadRelaxed() == QtGlobalStatic::Uninitialized) {
|
if (guard.loadRelaxed() == QtGlobalStatic::Uninitialized) {
|
||||||
QAS::innerFunction(realPointer());
|
QAS::innerFunction(&storage);
|
||||||
QObject::connect(QCoreApplication::instance(), &QObject::destroyed, reset);
|
QObject::connect(QCoreApplication::instance(), &QObject::destroyed, reset);
|
||||||
guard.storeRelaxed(QtGlobalStatic::Initialized);
|
guard.storeRelaxed(QtGlobalStatic::Initialized);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user