moc: deprecate use of int to return QFlags values
This code appears to be legacy from Qt 3's way of handling properties of enum types, because back then there was no QFlags and QVariant had a limited set of types it could use. To support flags and enum types, QObject::property() and setProperty() were coded to pass ints if the property had the isEnumType() flag set. This code was ported to the new (static) QMetaObject format in Qt 4 before QVariant gained support for user types. When QVariant gained support for user types, support for enums was changed to use the actual enum type in the property accessors, which compiles for non-scoped enums (C++11). This commit causes such code to produce a warning, to warn users that they need to update their API. I have found no use of this in Qt or Qt Creator code, but users may have something ported from Qt 3 that simply still worked. We do have one setter taking int in QtWidgets (QGroupBox::setAlignment), which isn't getting deprecated by this change because QFlags can still be constructed (without warning) from integers, through QFlag. GCC warning: qtmochelpers.h: In instantiation of ‘std::enable_if_t<...> QtMocHelpers::assignFlags(void*, I) [with ...]’: moc_flags-property-integer-access.cpp:92:49: required from here uint from a Q_PROPERTY that is a Q_FLAG is deprecated; please update to return the actual property's type [-Wdeprecated-declarations] qtmochelpers.h:104:13: note: declared here Clang warning: qtmochelpers.h:113:5: warning: 'assignFlagsFromInteger<ClassWithFlagsAccessAsInteger::Flag>' is deprecated: Returning int/uint from a Q_PROPERTY that is a Q_FLAG is deprecated; please update to return the actual property's type [-Wdeprecated-declarations] moc_flags-property-integer-access.cpp:92:31: note: in instantiation of function template specialization 'QtMocHelpers::assignFlags<QFlags<ClassWithFlagsAccessAsInteger::Flag>, unsigned int>' requested here See-also: https://lists.qt-project.org/pipermail/development/2024-September/045636.html Change-Id: I526db07389040483fc2efffd66895430a55ec62b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
4f47ee4de4
commit
39bb305416
@ -446,6 +446,33 @@ constexpr auto metaObjectData(uint flags, const Methods &methods, const Properti
|
||||
|
||||
#define QT_MOC_HAS_UINTDATA 1
|
||||
|
||||
template <typename T> inline std::enable_if_t<std::is_enum_v<T>> assignFlags(void *v, T t) noexcept
|
||||
{
|
||||
*static_cast<T *>(v) = t;
|
||||
}
|
||||
|
||||
template <typename T> inline std::enable_if_t<QtPrivate::IsQFlags<T>::value> assignFlags(void *v, T t) noexcept
|
||||
{
|
||||
*static_cast<T *>(v) = t;
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
|
||||
template <typename T>
|
||||
Q_DECL_DEPRECATED_X("Returning int/uint from a Q_PROPERTY that is a Q_FLAG is deprecated; "
|
||||
"please update to return the actual property's type")
|
||||
inline void assignFlagsFromInteger(QFlags<T> &f, int i) noexcept
|
||||
{
|
||||
f = QFlag(i);
|
||||
}
|
||||
|
||||
template <typename T, typename I>
|
||||
inline std::enable_if_t<QtPrivate::IsQFlags<T>::value && sizeof(T) == sizeof(int) && std::is_integral_v<I>>
|
||||
assignFlags(void *v, I i) noexcept
|
||||
{
|
||||
assignFlagsFromInteger(*static_cast<T *>(v), i);
|
||||
}
|
||||
#endif // Qt 7
|
||||
|
||||
} // namespace QtMocHelpers
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -1535,9 +1535,11 @@ void Generator::generateStaticMetacall()
|
||||
else if (p.gspec == PropertyDef::ReferenceSpec)
|
||||
fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s%s())); break;\n",
|
||||
propindex, prefix.constData(), p.read.constData());
|
||||
#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
|
||||
else if (auto eflags = cdef->enumDeclarations.value(p.type); eflags & EnumIsFlag)
|
||||
fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n",
|
||||
propindex, prefix.constData(), p.read.constData());
|
||||
fprintf(out, " case %d: QtMocHelpers::assignFlags<%s>(_v, %s%s()); break;\n",
|
||||
propindex, p.type.constData(), prefix.constData(), p.read.constData());
|
||||
#endif
|
||||
else if (p.read == "default")
|
||||
fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s().value(); break;\n",
|
||||
propindex, p.type.constData(), prefix.constData(), p.bind.constData());
|
||||
@ -1567,10 +1569,7 @@ void Generator::generateStaticMetacall()
|
||||
if (p.inPrivateClass.size()) {
|
||||
prefix += p.inPrivateClass + "->";
|
||||
}
|
||||
if (auto eflags = cdef->enumDeclarations.value(p.type); eflags & EnumIsFlag) {
|
||||
fprintf(out, " case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
|
||||
propindex, prefix.constData(), p.write.constData());
|
||||
} else if (p.write == "default") {
|
||||
if (p.write == "default") {
|
||||
fprintf(out, " case %d: {\n", propindex);
|
||||
fprintf(out, " %s%s().setValue(*reinterpret_cast< %s*>(_v));\n",
|
||||
prefix.constData(), p.bind.constData(), p.type.constData());
|
||||
|
@ -93,7 +93,17 @@ qt_internal_extend_target(tst_moc CONDITION CMAKE_CROSSCOMPILING
|
||||
)
|
||||
|
||||
if (${PROJECT_VERSION_MAJOR} LESS 7)
|
||||
qt_internal_extend_target(tst_moc SOURCES flags-property-integer-access.h)
|
||||
# This file intentional produces a warning, so we use qt_wrap_cpp so we can
|
||||
# suppress it.
|
||||
qt_wrap_cpp(flags_property_moc flags-property-integer-access.h)
|
||||
qt_internal_extend_target(tst_moc SOURCES ${flags_property_moc})
|
||||
if (CLANG OR GCC)
|
||||
set(Wno_deprecated "-Wno-deprecated-declarations")
|
||||
elseif (MSVC)
|
||||
# warning isn't triggering
|
||||
set(Wno_deprecated "-wd4996")
|
||||
endif()
|
||||
set_source_files_properties(${flags_property_moc} COMPILE_FLAGS "${Wno_deprecated}")
|
||||
endif()
|
||||
|
||||
if (UNIX AND (CLANG OR GCC OR QCC))
|
||||
|
Loading…
x
Reference in New Issue
Block a user