diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-11-23 09:08:10 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2020-12-01 21:41:51 +0000 |
commit | 0943ad02419f6215915e4a7c98949d1fd9b08c45 (patch) | |
tree | c4a9e0134b70ae6925fc624fbfbdba8a247029d1 /src | |
parent | 28b015342d000b8487c853153f1d93606d3c2add (diff) |
Containers: call constructors even for primitive types
Trivial types are automatically classified as Q_PRIMITIVE_TYPE,
but it doesn't mean that they can be initialized with memset(0)
(notably, pointers to data members on Itanium ABIs are initialized
with -1, not 0).
Drop that kind of optimization, and always value-initialize
objects in containers. Fix the documentation to match as well.
This is a rework of f6f68409a40beaa5f034c411dd7e296c7828d8fd and
82b13880b994ff9b87710e0729e32035ab3b63a4 in Qt 6.
[ChangeLog][QtCore][QTypeInfo] The semantics of Q_PRIMITIVE_TYPE
have been slightly changed. Qt now value-initializes types
marked as primitive (which, by default, include trivial types)
instead of simply using memset(0), which is wrong in some corner
cases.
Change-Id: Ib61396be883424e2f03a9f3bbce1eaddce6aa731
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit 76671a57b5418ec98fe2c94a963728ac3306dc82)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qglobal.cpp | 6 | ||||
-rw-r--r-- | src/corelib/tools/qarraydataops.h | 8 | ||||
-rw-r--r-- | src/corelib/tools/qvector.h | 27 |
3 files changed, 16 insertions, 25 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 51b8379b3d..12d76c0dca 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -4030,10 +4030,8 @@ bool qunsetenv(const char *varName) \list \li \c Q_PRIMITIVE_TYPE specifies that \a Type is a POD (plain old - data) type with no constructor or destructor, or else a type where - every bit pattern is a valid object; memset()ting memory to zero - creates a value-initialized instance of the type; and memcpy()ing - creates a valid independent copy of an object. + data) type with no constructor or destructor, and for which memcpy()ing + creates a valid independent copy of the object. \li \c Q_MOVABLE_TYPE specifies that \a Type has a constructor and/or a destructor but can be moved in memory using \c memcpy(). Note: despite the name, this has nothing to do with move diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 7e1b43f9b1..0579f78cac 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -65,8 +65,10 @@ struct QPodArrayOps Q_ASSERT(newSize > uint(this->size)); Q_ASSERT(newSize <= this->alloc); - ::memset(static_cast<void *>(this->end()), 0, (newSize - this->size) * sizeof(T)); - this->size = int(newSize); + T *const begin = this->begin(); + do { + new (begin + this->size) T(); + } while (uint(++this->size) != newSize); } void copyAppend(const T *b, const T *e) @@ -154,7 +156,7 @@ struct QGenericArrayOps T *const begin = this->begin(); do { - new (begin + this->size) T; + new (begin + this->size) T(); } while (uint(++this->size) != newSize); } diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 30fd7b2865..22a7a39faa 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -323,13 +323,8 @@ private: template <typename T> void QVector<T>::defaultConstruct(T *from, T *to) { - if (QTypeInfo<T>::isComplex) { - while (from != to) { - new (from++) T(); - } - } else { - ::memset(static_cast<void *>(from), 0, (to - from) * sizeof(T)); - } + while (from != to) + new (from++) T(); } template <typename T> @@ -599,17 +594,13 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo if (asize > d->size) { // construct all new objects when growing - if (!QTypeInfo<T>::isComplex) { - ::memset(static_cast<void *>(dst), 0, (static_cast<T *>(x->end()) - dst) * sizeof(T)); - } else { - QT_TRY { - while (dst != x->end()) - new (dst++) T(); - } QT_CATCH (...) { - // destruct already copied objects - destruct(x->begin(), dst); - QT_RETHROW; - } + QT_TRY { + while (dst != x->end()) + new (dst++) T(); + } QT_CATCH (...) { + // destruct already copied objects + destruct(x->begin(), dst); + QT_RETHROW; } } } QT_CATCH (...) { |