aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-11-01 14:11:37 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-11-04 03:52:18 +0000
commit590a47bc0cf557c36503df8ec493d826ae6c878d (patch)
treed5dba44419deae976c6493844d3cf167a300dda1
parent97f627eabebbacff910fa22ceb266a6ea06b2df6 (diff)
QmlCompiler: Extend shadow-checking
Method return values as well as whatever we hide behind "unknown" can contain shadowable properties. We need to check it. Pick-to: 6.5 6.2 Task-number: QTBUG-117800 Change-Id: I518bc11fd0c9c69340bf621198eeaf4c95d17dae Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> (cherry picked from commit 048c8f226ae09b79264e5dfc51f5d8fe7a8332a9) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/qmlcompiler/qqmljsshadowcheck.cpp6
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt3
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/ShadowedObjectName.qml6
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/ShadowedObjectNameDerived.qml6
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/shadowedAsCasts.qml31
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp31
6 files changed, 81 insertions, 2 deletions
diff --git a/src/qmlcompiler/qqmljsshadowcheck.cpp b/src/qmlcompiler/qqmljsshadowcheck.cpp
index 5b07140490..167396f614 100644
--- a/src/qmlcompiler/qqmljsshadowcheck.cpp
+++ b/src/qmlcompiler/qqmljsshadowcheck.cpp
@@ -114,10 +114,12 @@ void QQmlJSShadowCheck::checkShadowing(
return;
switch (baseType.variant()) {
- case QQmlJSRegisterContent::ObjectProperty:
case QQmlJSRegisterContent::ExtensionObjectProperty:
+ case QQmlJSRegisterContent::ExtensionScopeProperty:
+ case QQmlJSRegisterContent::MethodReturnValue:
+ case QQmlJSRegisterContent::ObjectProperty:
case QQmlJSRegisterContent::ScopeProperty:
- case QQmlJSRegisterContent::ExtensionScopeProperty: {
+ case QQmlJSRegisterContent::Unknown: {
const QQmlJSRegisterContent member = m_typeResolver->memberType(baseType, memberName);
// You can have something like parent.QtQuick.Screen.pixelDensity
diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
index 37d953ec8e..539fb39068 100644
--- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
@@ -53,6 +53,8 @@ set(qml_files
ProgressBar/TimelineAnimation.qml
RootWithoutId.qml
SelectionRectangle.qml
+ ShadowedObjectName.qml
+ ShadowedObjectNameDerived.qml
Test.qml
TestCase.qml
WindowDerived.qml
@@ -199,6 +201,7 @@ set(qml_files
script.mjs
sequenceToIterable.qml
setLookupConversion.qml
+ shadowedAsCasts.qml
shadowedMethod.qml
shared/Slider.qml
shifts.qml
diff --git a/tests/auto/qml/qmlcppcodegen/data/ShadowedObjectName.qml b/tests/auto/qml/qmlcppcodegen/data/ShadowedObjectName.qml
new file mode 100644
index 0000000000..f079f4a94e
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/ShadowedObjectName.qml
@@ -0,0 +1,6 @@
+pragma Strict
+import QtQml
+
+QtObject {
+ property int objectName: 12
+}
diff --git a/tests/auto/qml/qmlcppcodegen/data/ShadowedObjectNameDerived.qml b/tests/auto/qml/qmlcppcodegen/data/ShadowedObjectNameDerived.qml
new file mode 100644
index 0000000000..f988cd6bc9
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/ShadowedObjectNameDerived.qml
@@ -0,0 +1,6 @@
+pragma Strict
+import QtQml
+
+ShadowedObjectName {
+ property double objectName: 17.4
+}
diff --git a/tests/auto/qml/qmlcppcodegen/data/shadowedAsCasts.qml b/tests/auto/qml/qmlcppcodegen/data/shadowedAsCasts.qml
new file mode 100644
index 0000000000..ccb50f4934
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/shadowedAsCasts.qml
@@ -0,0 +1,31 @@
+pragma Strict
+import QtQml
+
+QtObject {
+ property ShadowedObjectName shadowed1: ShadowedObjectName {}
+ property ShadowedObjectName shadowed2: ShadowedObjectName {}
+ property QtObject shadowed3: ShadowedObjectNameDerived {}
+
+ function returnShadowed2() : QtObject { return shadowed2 }
+
+ function a(mark: int) {
+ // as-cast can be optimized out if we're clever.
+ (shadowed1 as QtObject).objectName = mark;
+ }
+
+ function b(mark: int) {
+ // method return values can contain shadowed properties!
+ returnShadowed2().objectName = mark;
+ }
+
+ function c(mark: int) {
+ // Has to do an actual as-cast, but results in ShadowedObjectNameDerived!
+ (shadowed3 as ShadowedObjectName).objectName = mark;
+ }
+
+ Component.onCompleted: {
+ a(43);
+ b(42);
+ c(41);
+ }
+}
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index b1e97b2560..a6a8f5db14 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -166,6 +166,7 @@ private slots:
void scopeVsObject();
void sequenceToIterable();
void setLookupConversion();
+ void shadowedAsCasts();
void shadowedMethod();
void shifts();
void signalHandler();
@@ -3478,6 +3479,36 @@ void tst_QmlCppCodegen::setLookupConversion()
QCOMPARE(o->objectName(), u"a"_s);
}
+void tst_QmlCppCodegen::shadowedAsCasts()
+{
+ QQmlEngine e;
+ QQmlComponent c(&e, QUrl(u"qrc:/qt/qml/TestTypes/shadowedAsCasts.qml"_s));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(!obj.isNull());
+
+ QObject *shadowed1 = obj->property("shadowed1").value<QObject *>();
+ QVERIFY(shadowed1);
+ QVERIFY(shadowed1->objectName().isEmpty());
+ const QVariant name1 = shadowed1->property("objectName");
+ QCOMPARE(name1.metaType(), QMetaType::fromType<int>());
+ QCOMPARE(name1.toInt(), 43);
+
+ QObject *shadowed2 = obj->property("shadowed2").value<QObject *>();
+ QVERIFY(shadowed2);
+ QVERIFY(shadowed2->objectName().isEmpty());
+ const QVariant name2 = shadowed2->property("objectName");
+ QCOMPARE(name2.metaType(), QMetaType::fromType<int>());
+ QCOMPARE(name2.toInt(), 42);
+
+ QObject *shadowed3 = obj->property("shadowed3").value<QObject *>();
+ QVERIFY(shadowed3);
+ QVERIFY(shadowed3->objectName().isEmpty());
+ const QVariant name3 = shadowed3->property("objectName");
+ QCOMPARE(name3.metaType(), QMetaType::fromType<double>());
+ QCOMPARE(name3.toDouble(), 41.0);
+}
+
void tst_QmlCppCodegen::shadowedMethod()
{
QQmlEngine e;