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 cb43aaca11
("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>
This commit is contained in:
parent
7211771c64
commit
2d0c31e7d9
@ -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;
|
||||
|
@ -477,8 +477,8 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
||||
// Output parameters are references; type id not available
|
||||
typeName = QMetaType(type).name();
|
||||
typeName.append('&');
|
||||
type = QMetaType::UnknownType;
|
||||
}
|
||||
Q_ASSERT(type != QMetaType::UnknownType);
|
||||
int typeInfo;
|
||||
if (!typeName.isEmpty())
|
||||
typeInfo = IsUnresolvedType | strings.enter(typeName);
|
||||
|
Loading…
Reference in New Issue
Block a user