diff options
| author | Marc Mutz <marc.mutz@qt.io> | 2025-06-06 19:39:58 +0200 |
|---|---|---|
| committer | Marc Mutz <marc.mutz@qt.io> | 2025-06-09 20:36:21 +0000 |
| commit | 49db71bb1995d8fa71afedb9b461d5203fbe49b1 (patch) | |
| tree | 30d3ea02bd3613515c92dbbcfdda9f26d7161438 /src/corelib/tools/qcontiguouscache.cpp | |
| parent | 4896448ffd54178c3e9fa2cba0070ce3a936ed05 (diff) | |
QContiguousCache: drag the initialization of atomic ref behind ABI boundary
All callers of QContiguousCache<T>::allocateData() followed the call
with a storeRelaxed(1) to the ref member. So we can just drag that
into the function itself.
Next, it's UB to storeRelaxed() into a default-constructed std::atomic
(and, therefore, into a QBasicAtomicInt), because until C++17
(inclusive) you're supposed to use std::atomic_init to assign the
first (and only the first) value to a default-constructed
std::atomic. QBasicAtomic doesn't have API for that, so you can never
assign anything to a default-constructed QBasicAtomic.
To fix, use placement new to be able to create a QBasicAtomic directly
with an initial value (replacing QBasicAtomic with QAtomic wouldn't
help here, either, since a malloc doesn't run ctors).
A proper fix has to wait until we can depend on C++20's atomic_ref,
which decouples the underlying type from the atomic operations
performed on it, letting us depend on malloc's zero-initialization
of an int member properly initializing it even for a following atomic
operation on it.
Task-number: QTBUG-137465
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ic22d0766bcffb967a86c8ec28b63ee480aebd4a0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qcontiguouscache.cpp')
| -rw-r--r-- | src/corelib/tools/qcontiguouscache.cpp | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/corelib/tools/qcontiguouscache.cpp b/src/corelib/tools/qcontiguouscache.cpp index 4a3fd73dc1f..6ca739c3059 100644 --- a/src/corelib/tools/qcontiguouscache.cpp +++ b/src/corelib/tools/qcontiguouscache.cpp @@ -22,7 +22,8 @@ void QContiguousCacheData::dump() const QContiguousCacheData *QContiguousCacheData::allocateData(qsizetype size, qsizetype alignment) { - return static_cast<QContiguousCacheData *>(qMallocAligned(size_t(size), size_t(alignment))); + void *mem = qMallocAligned(size_t(size), size_t(alignment)); + return new (mem) QContiguousCacheData{/*ref=*/1, 0, 0, 0, 0}; } void QContiguousCacheData::freeData(QContiguousCacheData *data) |
