diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2016-01-03 11:27:09 -0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2016-01-12 19:25:42 +0000 |
commit | 70092c9a47840e1ca7606b90075b364c69876656 (patch) | |
tree | 29f115b72a141aeaed0c1d1f5fa8e92bd3350f8d /src/corelib/kernel/qvariant_p.h | |
parent | 9f09fed72f87c9379fcbfd51cd6463b5c470814f (diff) |
Fix GCC 6 warning about placement-new operator on too little space
GCC 6 is able to detect when you use a placement new of an object in a
space that is too small to contain it.
qvariant_p.h: In instantiation of ‘void v_construct(QVariant::Private*, const T&) [with T = QRectF]’:
qvariant_p.h:142:9: error: placement new constructing an object of type ‘QRectF’ and size ‘32’ in a region of type ‘void*’ and size ‘8’ [-Werror=placement-new]
new (&x->data.ptr) T(t);
^~~~~~~~~~~~~~~~~~~~~~~
This happens even for the false branch of a constant expression (the
enum). So split the v_construct function in two pairs, one pair for
being able to use the internal space and one pair not so.
Change-Id: Ibc83b9f7e3bc4962ae35ffff1425ed898f279dea
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com>
Diffstat (limited to 'src/corelib/kernel/qvariant_p.h')
-rw-r--r-- | src/corelib/kernel/qvariant_p.h | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index 4a7df1ad8d..337e1406ec 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -60,6 +60,7 @@ struct QVariantIntegrator { static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data) && ((QTypeInfoQuery<T>::isRelocatable) || Q_IS_ENUM(T)); + typedef QtPrivate::integral_constant<bool, CanUseInternalSpace> CanUseInternalSpace_t; }; Q_STATIC_ASSERT(QVariantIntegrator<double>::CanUseInternalSpace); Q_STATIC_ASSERT(QVariantIntegrator<long int>::CanUseInternalSpace); @@ -110,31 +111,49 @@ private: T m_t; }; -// constructs a new variant if copy is 0, otherwise copy-constructs template <class T> -inline void v_construct(QVariant::Private *x, const void *copy, T * = 0) +inline void v_construct_helper(QVariant::Private *x, const T &t, QtPrivate::true_type) { - if (!QVariantIntegrator<T>::CanUseInternalSpace) { - x->data.shared = copy ? new QVariantPrivateSharedEx<T>(*static_cast<const T *>(copy)) - : new QVariantPrivateSharedEx<T>; - } else { - if (copy) - new (&x->data.ptr) T(*static_cast<const T *>(copy)); - else - new (&x->data.ptr) T(); - } - x->is_shared = !QVariantIntegrator<T>::CanUseInternalSpace; + new (&x->data) T(t); + x->is_shared = false; +} + +template <class T> +inline void v_construct_helper(QVariant::Private *x, const T &t, QtPrivate::false_type) +{ + x->data.shared = new QVariantPrivateSharedEx<T>(t); + x->is_shared = true; +} + +template <class T> +inline void v_construct_helper(QVariant::Private *x, QtPrivate::true_type) +{ + new (&x->data) T(); + x->is_shared = false; +} + +template <class T> +inline void v_construct_helper(QVariant::Private *x, QtPrivate::false_type) +{ + x->data.shared = new QVariantPrivateSharedEx<T>; + x->is_shared = true; } template <class T> inline void v_construct(QVariant::Private *x, const T &t) { - if (!QVariantIntegrator<T>::CanUseInternalSpace) { - x->data.shared = new QVariantPrivateSharedEx<T>(t); - } else { - new (&x->data.ptr) T(t); - } - x->is_shared = !QVariantIntegrator<T>::CanUseInternalSpace; + // dispatch + v_construct_helper(x, t, typename QVariantIntegrator<T>::CanUseInternalSpace_t()); +} + +// constructs a new variant if copy is 0, otherwise copy-constructs +template <class T> +inline void v_construct(QVariant::Private *x, const void *copy, T * = 0) +{ + if (copy) + v_construct<T>(x, *static_cast<const T *>(copy)); + else + v_construct_helper<T>(x, typename QVariantIntegrator<T>::CanUseInternalSpace_t()); } // deletes the internal structures |