diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2022-07-15 22:31:56 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-07-27 14:51:46 -0700 |
commit | 2d0c31e7d92a3e9df4ce2b9c1d41b94fb12735fc (patch) | |
tree | 5e5ef9228a12d9cc8f7dc2bb8802019147c75088 /src/corelib/kernel/qmetatype.h | |
parent | 7211771c64caad7880212b1a35d4a6070800c0fa (diff) |
QMetaType: fix QMetaTypes for non-const references
Namely, they shouldn't be supported. Even trying to create such a type
(as in QMetaType::fromType<int &>()) should fail, because for the
purposes of the meta type, they are not the same.
However, they were being registered in the meta objects' meta type list
as a mistake since commit cb43aaca112c864a201b87037692cb8ae2e93b6d
("Introduce QMetaObject::metaType"), including for output parameters in
D-Bus remote objects' meta objects. despite the comment saying "type id
not available".
[ChangeLog][Potentially Source-incompatible Changes] Made meta types for
non-const references fail to compile. Previously, QMetaType::fromType
allowed this to compile, but returned the meta type for the base type,
which was incorrect. Const references are understood to be the same as
the base type.
[ChangeLog][Important Behavior Changes] The meta type for non-const
reference parameters in extracted methods (signals, slots, etc.) is no
longer available in QMetaMethod. This used to be the case in Qt 4.x and
5.x, but due to a mistake in Qt 6.0-6.3, QMetaMethod would incorrectly
report the base (non-reference) type. Additionally, both the reference
and the non-reference types may have been reported in different APIs.
Pick-to: 6.4
Change-Id: I36b24183fbd041179f2ffffd1702384d2b64a5f9
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 18d59e1298..ae13590658 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -843,7 +843,11 @@ namespace QtPrivate } // namespace detail template <typename T, typename ODR_VIOLATION_PREVENTER> - struct is_complete : detail::is_complete_helper<T, ODR_VIOLATION_PREVENTER>::type {}; + struct is_complete : detail::is_complete_helper<std::remove_reference_t<T>, ODR_VIOLATION_PREVENTER>::type {}; + + template <typename T> struct MetatypeDecay { using type = T; }; + template <typename T> struct MetatypeDecay<const T> { using type = T; }; + template <typename T> struct MetatypeDecay<const T &> { using type = T; }; template<typename T> struct IsPointerToTypeDerivedFromQObject @@ -2478,12 +2482,6 @@ QT_FOR_EACH_STATIC_CORE_POINTER(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER) QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER) #undef QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER #endif -template<typename T> -constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType() -{ - using Ty = std::remove_cv_t<std::remove_reference_t<T>>; - return &QMetaTypeInterfaceWrapper<Ty>::metaType; -} template<typename T> struct qRemovePointerLike @@ -2510,14 +2508,26 @@ struct TypeAndForceComplete using ForceComplete = ForceComplete_; }; +template<typename T> +constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType() +{ + using Ty = typename MetatypeDecay<T>::type; + return &QMetaTypeInterfaceWrapper<Ty>::metaType; +} + template<typename Unique, typename TypeCompletePair> constexpr const QMetaTypeInterface *qTryMetaTypeInterfaceForType() { using T = typename TypeCompletePair::type; using ForceComplete = typename TypeCompletePair::ForceComplete; - using Ty = std::remove_cv_t<std::remove_reference_t<T>>; + using Ty = typename MetatypeDecay<T>::type; using Tz = qRemovePointerLike_t<Ty>; - if constexpr (!is_complete<Tz, Unique>::value && !ForceComplete::value) { + + if constexpr (ForceComplete::value) { + return &QMetaTypeInterfaceWrapper<Ty>::metaType; + } else if constexpr (std::is_reference_v<Tz>) { + return nullptr; + } else if constexpr (!is_complete<Tz, Unique>::value) { return nullptr; } else { return &QMetaTypeInterfaceWrapper<Ty>::metaType; |