diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2022-07-20 09:09:56 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-07-27 14:51:58 -0700 |
commit | 1b96b645ec848ce911ecedbbb31d21b1b2c9d58b (patch) | |
tree | fc2ae900494b2eefb55e07d9f3607b836e163a2e /src/corelib/kernel/qmetatype.cpp | |
parent | 3695b35dfc427f274e55f8e2a6a9876deb52f1b4 (diff) |
QMetaType: prevent memory leak on create() if the constructor throws
The #ifdef wasn't necessary because destroy() had been using
__STDCPP_DEFAULT_NEW_ALIGNMENT__ without #if.
Change-Id: I3859764fed084846bcb0fffd17039570283d3eaf
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/kernel/qmetatype.cpp')
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index f7fa838911..103b3190a2 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -68,6 +68,18 @@ QT_IMPL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl, QPa using QtMetaTypePrivate::isInterfaceFor; namespace { +struct QMetaTypeDeleter +{ + const QtPrivate::QMetaTypeInterface *iface; + void operator()(void *data) + { + if (iface->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { + operator delete(data, std::align_val_t(iface->alignment)); + } else { + operator delete(data); + } + } +}; struct QMetaTypeCustomRegistry { @@ -611,14 +623,14 @@ void *QMetaType::create(const void *copy) const if (copy ? !isCopyConstructible() : !isDefaultConstructible()) return nullptr; - void *where = -#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__ - d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__ ? - operator new(d_ptr->size, std::align_val_t(d_ptr->alignment)) : -#endif - operator new(d_ptr->size); - QtMetaTypePrivate::construct(d_ptr, where, copy); - return where; + std::unique_ptr<void, QMetaTypeDeleter> where(nullptr, {d_ptr}); + if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) + where.reset(operator new(d_ptr->size, std::align_val_t(d_ptr->alignment))); + else + where.reset(operator new(d_ptr->size)); + + QtMetaTypePrivate::construct(d_ptr, where.get(), copy); + return where.release(); } /*! @@ -634,11 +646,7 @@ void QMetaType::destroy(void *data) const { if (data && isDestructible()) { QtMetaTypePrivate::destruct(d_ptr, data); - if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { - operator delete(data, std::align_val_t(d_ptr->alignment)); - } else { - operator delete(data); - } + QMetaTypeDeleter{d_ptr}(data); } } |