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 81a31beeb2, which changed
Q_APPLICATION_STATIC to use inline aligned_union storage instead of
the original implementation's unique_ptr.
Pick-to: 6.5 6.4
Change-Id: I065bd33812a40195109bf11d5bc79975f2f87cd5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
parent
d3f8d7fd41
commit
c53fdcb5ee
|
|
@ -9,6 +9,8 @@
|
|||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qglobalstatic.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtGlobalStatic {
|
||||
|
|
@ -36,7 +38,7 @@ template <typename QAS> struct ApplicationHolder
|
|||
|
||||
static PlainType *realPointer()
|
||||
{
|
||||
return reinterpret_cast<PlainType *>(&storage);
|
||||
return std::launder(reinterpret_cast<PlainType *>(&storage));
|
||||
}
|
||||
|
||||
// called from QGlobalStatic::instance()
|
||||
|
|
@ -46,7 +48,7 @@ template <typename QAS> struct ApplicationHolder
|
|||
return realPointer();
|
||||
QMutexLocker locker(&mutex);
|
||||
if (guard.loadRelaxed() == QtGlobalStatic::Uninitialized) {
|
||||
QAS::innerFunction(realPointer());
|
||||
QAS::innerFunction(&storage);
|
||||
QObject::connect(QCoreApplication::instance(), &QObject::destroyed, reset);
|
||||
guard.storeRelaxed(QtGlobalStatic::Initialized);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue