diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-24 01:01:06 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-10-24 15:42:35 +0200 |
commit | 328b97a0acdf294f6ba3c902d23ece374a0f11ba (patch) | |
tree | 3a005d1948a91bfaacda69dc0dfba1b66d491714 /src/qml/qml | |
parent | 1e94466b06190061a86e9918c5e45279171e600f (diff) | |
parent | 45652a0491aa32ecdf1d05c236501f78bcea71f8 (diff) |
Merge remote-tracking branch 'origin/5.14' into 5.15
Conflicts:
src/qml/qml/qqmlpropertyvalidator.cpp
tests/auto/qml/qmlmin/tst_qmlmin.cpp
Change-Id: I920c133e839d980ed32c179a0bc4fa44c46e2296
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/ftw/qflagpointer_p.h | 16 | ||||
-rw-r--r-- | src/qml/qml/ftw/qqmlthread.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlcontext.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertyvalidator.cpp | 4 |
6 files changed, 37 insertions, 4 deletions
diff --git a/src/qml/qml/ftw/qflagpointer_p.h b/src/qml/qml/ftw/qflagpointer_p.h index 71b41cd30b..a10e57aeca 100644 --- a/src/qml/qml/ftw/qflagpointer_p.h +++ b/src/qml/qml/ftw/qflagpointer_p.h @@ -55,6 +55,17 @@ QT_BEGIN_NAMESPACE +namespace QtPrivate { +template <typename T> struct QFlagPointerAlignment +{ + enum : size_t { Value = Q_ALIGNOF(T) }; +}; +template <> struct QFlagPointerAlignment<void> +{ + enum : size_t { Value = ~size_t(0) }; +}; +} + template<typename T> class QFlagPointer { public: @@ -133,6 +144,7 @@ template<typename T> QFlagPointer<T>::QFlagPointer(T *v) : ptr_value(quintptr(v)) { + Q_STATIC_ASSERT_X(Q_ALIGNOF(T) >= 4, "Type T does not have sufficient alignment"); Q_ASSERT((ptr_value & FlagsMask) == 0); } @@ -247,6 +259,8 @@ template<typename T, typename T2> QBiPointer<T, T2>::QBiPointer(T *v) : ptr_value(quintptr(v)) { + Q_STATIC_ASSERT_X(QtPrivate::QFlagPointerAlignment<T>::Value >= 4, + "Type T does not have sufficient alignment"); Q_ASSERT((quintptr(v) & FlagsMask) == 0); } @@ -254,6 +268,8 @@ template<typename T, typename T2> QBiPointer<T, T2>::QBiPointer(T2 *v) : ptr_value(quintptr(v) | Flag2Bit) { + Q_STATIC_ASSERT_X(QtPrivate::QFlagPointerAlignment<T2>::Value >= 4, + "Type T2 does not have sufficient alignment"); Q_ASSERT((quintptr(v) & FlagsMask) == 0); } diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp index e961ed3d0d..7d2ad354d6 100644 --- a/src/qml/qml/ftw/qqmlthread.cpp +++ b/src/qml/qml/ftw/qqmlthread.cpp @@ -131,6 +131,9 @@ QQmlThreadPrivate::QQmlThreadPrivate(QQmlThread *q) m_mainThreadWaiting(false), mainSync(nullptr), m_mainObject(this) { setObjectName(QStringLiteral("QQmlThread")); + // This size is aligned with the recursion depth limits in the parser/codegen. In case of + // absurd content we want to hit the recursion checks instead of running out of stack. + setStackSize(8 * 1024 * 1024); } bool QQmlThreadPrivate::event(QEvent *e) diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index 254b6cc3db..9157bb95c3 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -532,6 +532,9 @@ QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, int ind void QQmlContextPrivate::dropDestroyedQObject(const QString &name, QObject *destroyed) { + if (!data->isValid()) + return; + const int idx = data->propertyNames().value(name); Q_ASSERT(idx >= 0); if (qvariant_cast<QObject *>(propertyValues[idx]) != destroyed) diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 73546bd795..21ca24d38b 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1824,7 +1824,8 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader, if (qmldirPath.size() > 25 && qmldirPath.at(0) == QLatin1Char(':') && qmldirPath.at(1) == QLatin1Char('/') && qmldirPath.startsWith(QStringLiteral(":/android_rcc_bundle/qml/"), Qt::CaseInsensitive)) { QString pluginName = qmldirPath.mid(21) + Slash + baseName; - auto bundledPath = resolvedPath + QLatin1String("lib") + pluginName.replace(QLatin1Char('/'), QLatin1Char('_')); + pluginName.replace(QLatin1Char('/'), QLatin1Char('_')); + QString bundledPath = resolvedPath + QLatin1String("lib") + pluginName; for (const QString &suffix : suffixes) { const QString absolutePath = typeLoader->absoluteFilePath(bundledPath + suffix); if (!absolutePath.isEmpty()) diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index eff3e94fbd..9e6819891c 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1373,8 +1373,9 @@ bool QQmlPropertyPrivate::write(QObject *object, } } if (!ok) { - // the only other option is that they are assigning a single value + // the only other options are that they are assigning a single value // to a sequence type property (eg, an int to a QList<int> property). + // or that we encountered an interface type // Note that we've already handled single-value assignment to QList<QUrl> properties. if (variantType == QVariant::Int && propertyType == qMetaTypeId<QList<int> >()) { QList<int> list; @@ -1405,6 +1406,15 @@ bool QQmlPropertyPrivate::write(QObject *object, } } + if (!ok && QQmlMetaType::isInterface(propertyType)) { + auto valueAsQObject = qvariant_cast<QObject *>(value); + if (valueAsQObject && valueAsQObject->qt_metacast(QQmlMetaType::interfaceIId(propertyType))) { + // this case can occur when object has an interface type + // and the variant contains a type implementing the interface + return property.writeProperty(object, const_cast<void *>(value.constData()), flags); + } + } + if (ok) { return property.writeProperty(object, const_cast<void *>(v.constData()), flags); } else { diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index d7361ea2c6..238a535b89 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -728,12 +728,12 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPrope return noError; } else if (isPrimitiveType(propType)) { auto typeName = QString::fromUtf8(QMetaType::typeName(propType)); - return qQmlCompileError(binding->location, tr("Can not assign value of type \"%1\" to property \"%2\", expecting \"%3\"") + return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting \"%3\"") .arg(rhsType()) .arg(propertyName) .arg(typeName)); } else if (QQmlValueTypeFactory::isValueType(propType)) { - return qQmlCompileError(binding->location, tr("Can not assign value of type \"%1\" to property \"%2\", expecting an object") + return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting an object") .arg(rhsType()).arg(propertyName)); } else if (propType == qMetaTypeId<QQmlScriptString>()) { return qQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected")); |