summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-07-20 09:09:56 -0700
committerThiago Macieira <thiago.macieira@intel.com>2022-07-27 14:51:58 -0700
commit1b96b645ec848ce911ecedbbb31d21b1b2c9d58b (patch)
treefc2ae900494b2eefb55e07d9f3607b836e163a2e /src/corelib/kernel/qmetatype.cpp
parent3695b35dfc427f274e55f8e2a6a9876deb52f1b4 (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.cpp34
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);
}
}