QRegion: fix potential UB in QBasicAtomic initialization
Until C++17 (inclusive), a default-constructed std::atomic object can, officially, only be initialized with a call to std::atomic_init, for which QBasicAtomic doesn't have API. It is even unclear whether zero-initialization of static and thread-local objects will cause the object to be initialized. QRegion is using QtPrivate::RefCount, but that's just another wrapper around QBasicAtomic, so it has the same problems: it must always be initialized. So don't default-construct and then storeRelaxed() (via initializeOwned()), use NSDMI with (newly-added) Q_REFCOUNT_INITIALIZE_OWNED to avoid this dark language corner. Task-number: QTBUG-137465 Pick-to: 6.9 6.8 6.5 Change-Id: I4b765aed329211984c35c40fbc5648bf104990ce Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 5aefe2d9a1d56f6134fcbbdff260c79082eea661) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
ee0cb525cd
commit
2b0ec367c7
@ -50,6 +50,7 @@ public:
|
||||
}
|
||||
|
||||
#define Q_REFCOUNT_INITIALIZE_STATIC { Q_BASIC_ATOMIC_INITIALIZER(-1) }
|
||||
#define Q_REFCOUNT_INITIALIZE_OWNED { Q_BASIC_ATOMIC_INITIALIZER(1) }
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -3812,7 +3812,6 @@ QRegion::QRegion(const QRect &r, RegionType t)
|
||||
d = const_cast<QRegionData*>(&shared_empty);
|
||||
} else {
|
||||
d = new QRegionData;
|
||||
d->ref.initializeOwned();
|
||||
if (t == Rectangle) {
|
||||
d->qt_rgn = new QRegionPrivate(r);
|
||||
} else if (t == Ellipse) {
|
||||
@ -3831,7 +3830,6 @@ QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule)
|
||||
fillRule == Qt::WindingFill ? WindingRule : EvenOddRule);
|
||||
if (qt_rgn) {
|
||||
d = new QRegionData;
|
||||
d->ref.initializeOwned();
|
||||
d->qt_rgn = qt_rgn;
|
||||
} else {
|
||||
d = const_cast<QRegionData*>(&shared_empty);
|
||||
@ -3854,7 +3852,6 @@ QRegion::QRegion(const QBitmap &bm)
|
||||
d = const_cast<QRegionData*>(&shared_empty);
|
||||
} else {
|
||||
d = new QRegionData;
|
||||
d->ref.initializeOwned();
|
||||
d->qt_rgn = qt_bitmapToRegion(bm);
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ Q_GUI_EXPORT
|
||||
void exec(const QByteArray &ba, int ver = 0, QDataStream::ByteOrder byteOrder = QDataStream::BigEndian);
|
||||
#endif
|
||||
struct QRegionData {
|
||||
QtPrivate::RefCount ref;
|
||||
QtPrivate::RefCount ref = Q_REFCOUNT_INITIALIZE_OWNED;
|
||||
QRegionPrivate *qt_rgn;
|
||||
};
|
||||
struct QRegionData *d;
|
||||
|
Loading…
x
Reference in New Issue
Block a user