QMetaType: force properties to have a complete type again

When the compile time metatype support for methods was introduced, we
needed to allow incomplete types to avoid breaking a large amount of
code. However, this mistakenly enabled using incomplete types for
properties, too. In contrast to methods, properties lack the fallback
code to retrieve the metatype at runtime. Thus, this commit restores the
completeness requirement for properties again. This is done by always
calling QMetaTypeForType for properties in qTryMetaTypeForType.
Amends fa987d44417528856d5e80ed7b48ba99e19fa307

Change-Id: I5f66ff289631c056eecebe40926bf321d283eea7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Fabian Kosmale 2020-07-22 11:21:42 +02:00
parent af7a3430ed
commit 27fcf66319
2 changed files with 27 additions and 6 deletions

View File

@ -2828,12 +2828,21 @@ template<typename T>
using qRemovePointerLike_t = typename qRemovePointerLike<T>::type;
#undef Q_REMOVE_POINTER_LIKE_IMPL
template<typename Unique, typename T>
template<typename T, typename ForceComplete_>
struct TypeAndForceComplete
{
using type = T;
using ForceComplete = ForceComplete_;
};
template<typename Unique, typename TypeCompletePair>
constexpr QMetaTypeInterface *qTryMetaTypeInterfaceForType()
{
using T = typename TypeCompletePair::type;
using ForceComplete = typename TypeCompletePair::ForceComplete;
using Ty = std::remove_cv_t<std::remove_reference_t<T>>;
using Tz = qRemovePointerLike_t<Ty>;
if constexpr (!is_complete<Tz, Unique>::value) {
if constexpr (!is_complete<Tz, Unique>::value && !ForceComplete::value) {
return nullptr;
} else {
return &QMetaTypeForType<Ty>::metaType;

View File

@ -580,17 +580,26 @@ void Generator::generateCode()
}
for (int i = 0; i < cdef->propertyList.count(); ++i) {
const PropertyDef &p = cdef->propertyList.at(i);
fprintf(out, "%s%s", needsComma ? ", " : "", p.type.data());
if (requireCompleteTypes)
fprintf(out, "%s%s", needsComma ? ", " : "", p.type.data());
else
fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::true_type>", needsComma ? ", " : "", p.type.data());
needsComma = true;
}
for (const QList<FunctionDef> &methodContainer :
{ cdef->signalList, cdef->slotList, cdef->methodList }) {
for (int i = 0; i< methodContainer.count(); ++i) {
const FunctionDef& fdef = methodContainer.at(i);
fprintf(out, "%s%s", needsComma ? ", " : "", fdef.type.name.data());
if (requireCompleteTypes)
fprintf(out, "%s%s", needsComma ? ", " : "", fdef.type.name.data());
else
fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::false_type>", needsComma ? ", " : "", fdef.type.name.data());
needsComma = true;
for (const auto &argument: fdef.arguments) {
fprintf(out, ", %s", argument.type.name.data());
if (requireCompleteTypes)
fprintf(out, ", %s", argument.type.name.data());
else
fprintf(out, ", QtPrivate::TypeAndForceComplete<%s, std::false_type>", argument.type.name.data());
}
}
fprintf(out, "\n");
@ -598,7 +607,10 @@ void Generator::generateCode()
for (int i = 0; i< cdef->constructorList.count(); ++i) {
const FunctionDef& fdef = cdef->constructorList.at(i);
for (const auto &argument: fdef.arguments) {
fprintf(out, "%s%s", needsComma ? ", " : "", argument.type.name.data());
if (requireCompleteTypes)
fprintf(out, "%s%s", needsComma ? ", " : "", argument.type.name.data());
else
fprintf(out, "%sQtPrivate::TypeAndForceComplete<%s, std::false_type>", needsComma ? ", " : "", argument.type.name.data());
needsComma = true;
}
}