From 46f6a10663a5ee6dd34d690b7d9fbd6e91aebe13 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 3 Feb 2023 17:31:11 +0100 Subject: [PATCH] Fix QVariant(QString) <-> enum conversion A QVariant(QString) was not convertible to an enum not registered with Q_ENUM() which worked fine in Qt5. The same problem exists for QVariant(enum) to QString. Fix it by not bailing out when no metatype for the enum was found and try to convert it to a qlonglong instead (which is then correctly converted to the enum type). Fixes: QTBUG-109744 Change-Id: Ie7bb016a860455b69508f0f46b36474c9c294f3a Reviewed-by: Thiago Macieira (cherry picked from commit 66a1a71f1f92156548da487739129fb0f494c895) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qmetatype.cpp | 15 ++++++++------- .../auto/corelib/kernel/qvariant/tst_qvariant.cpp | 7 +++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 3606b298dd1..139c4ec7762 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1947,7 +1947,6 @@ static bool convertFromEnum(QMetaType fromType, const void *from, QMetaType toTy if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray) return QMetaType::convert(QMetaType::fromType(), &ll, toType, to); } - Q_ASSERT(toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray); #ifndef QT_NO_QOBJECT QMetaEnum en = metaEnumFromType(fromType); if (en.isValid()) { @@ -1967,6 +1966,8 @@ static bool convertFromEnum(QMetaType fromType, const void *from, QMetaType toTy return true; } #endif + if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray) + return QMetaType::convert(QMetaType::fromType(), &ll, toType, to); return false; } @@ -1978,12 +1979,12 @@ static bool convertToEnum(QMetaType fromType, const void *from, QMetaType toType #ifndef QT_NO_QOBJECT if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) { QMetaEnum en = metaEnumFromType(toType); - if (!en.isValid()) - return false; - QByteArray keys = (fromTypeId == QMetaType::QString) - ? static_cast(from)->toUtf8() - : *static_cast(from); - value = en.keysToValue(keys.constData(), &ok); + if (en.isValid()) { + QByteArray keys = (fromTypeId == QMetaType::QString) + ? static_cast(from)->toUtf8() + : *static_cast(from); + value = en.keysToValue(keys.constData(), &ok); + } } #endif if (!ok) { diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index fbd17f94b28..87b9e20770f 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -4982,6 +4982,13 @@ template static void testVariantEnum() QVERIFY(var2.convert(QMetaType::fromType())); QCOMPARE(var2.value(), static_cast(value)); + QVariant strVar = QString::number(qToUnderlying(value)); + QVariant baVar = QByteArray::number(qToUnderlying(value)); + QCOMPARE(strVar.value(), value); + QCOMPARE(baVar.value(), value); + QCOMPARE(var.value(), strVar); + QCOMPARE(var.value(), baVar); + // unary + to silence gcc warning if (losslessConvertToInt) { int intValue = static_cast(value);