summaryrefslogtreecommitdiff
path: root/src/qmlcompiler
Commit message (Collapse)AuthorAgeFilesLines
* QmlCompiler: Do check specificType on SetLookupUlf Hermann2023-05-151-2/+7
| | | | | | | | | | We may have implicitly invalidated it when shadow-checking. Amends commit b3281f123ea5a8c0e5f8c63fa1568cf7414f9c14. Change-Id: Ia5c54a3a0fa97c61e947ecb0a5b21d410e1bf19a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* qmllint: Separate logic by import type in QQmlJSImportVisitor::visitOlivier De Cannière2023-05-122-46/+69
| | | | | | | | | | | | | | This patch reorganizes the logic of the import visitor to deal with each import type (paths, qrc: urls, file: urls) separately. This reorganisation fixes QTBUG-108803 which happened because "qrc:" imports were being treated as paths leading to things like ":/untitled/qrc:/untitled/components". Fixes: QTBUG-108803 Pick-to: 6.5 Change-Id: I5af20d10c533455215895be66b5cd98a977fd18a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QmlCompiler: Improve argument construction in generated codeUlf Hermann2023-05-111-28/+17
| | | | | | | | | | | | | We don't have to pass types that don't fit if we actually have the correct types in suitable wrappers. This still invokes the internal conversions of the call frame setup if we call with really generic types, for example if the same value is read multiple times with different target types. However, that is acceptable. Fixes: QTBUG-113465 Change-Id: I8ec4afeb39bbe6585e5268c0e9b0cfd2788d761a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Optimize list manipulationsUlf Hermann2023-05-103-38/+36
| | | | | | | | | | | | | | | | | We should never store a list in a wrapper type that is itself a different list. Wrapping and unwrapping requires rebuilding the list in such cases. We can, however, store lists of builtins as-is. There is no need to transform them. Other lists can still be stored in QVariant. As a result, we now need to discern between the access semantics of the stored type and the access semantics of the contained type. They are not guaranteed to be the same anymore. Furthermore, we need to reject "internal" manipulation of QVariant-wrapped lists for now. We might implement them using QMetaSequence, though. Task-number: QTBUG-113465 Change-Id: If09ea345b2fac39bf2abd62a2fce2d354df85b6b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Re-allow conversion from QObject to QStringUlf Hermann2023-05-091-1/+1
| | | | | | | | | | | | It only worked for the console functions in 6.5. There it was suppressed by the enforcement of type conversions in the basic blocks pass in dev. We have, however, a good enough way to coerce QObject to QString these days. Task-number: QTBUG-112291 Change-Id: I025976cc7fbe430c5cdc607cae3ca48838b24f88 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Properly support lists as method argumentsUlf Hermann2023-05-093-4/+16
| | | | | | | | | | | a, Teach QV4::QObjectWrapper how to convert QQmlListProperty to QObjectList. b, Parse the isList attribute from qmltypes. c, Resolve lists when resolving QQmlJSScope. Change-Id: I70c6d40507de990b45a87eb7d8c7bba279d550e8 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Generate trace info for ConvertThisToObjectUlf Hermann2023-05-091-0/+2
| | | | | | Change-Id: I021b8bea01cfcccd062b7e23d265208ae6b3e490 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Fix operator== of VirtualRegisterUlf Hermann2023-05-051-1/+2
| | | | | | | | | | This should not happen, but let's better be safe than sorry. Amends commit 4634b6bf54e5ba15aa2e8efc12feb156e3d9c309. Change-Id: I0bac55e8ce4518b2d90f19ea28d58ed629659778 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QmlCompiler: Convert thisObject to correct typeUlf Hermann2023-05-041-1/+4
| | | | | | | Amends commit 365b781599993aef933228599eaeb6eb909d9a93. Change-Id: I5775d634ef4e5204cdec2f440b1992b7272866d2 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmllint: Do not crash on invalid aliasFabian Kosmale2023-05-041-1/+3
| | | | | | | | | We handle already multiple invalid alias constructs, but the case where the alias is illegal without being an expression was not handled so far. Pick-to: 6.5 Change-Id: If85bc4b61f645a8f1eff3afa4da394c7373d8d53 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QmlCompiler: Disallow reading from values affected by side effectsUlf Hermann2023-05-046-45/+56
| | | | | | | | | | | | | | Instead of accepting the inconsistency between interpreter and compiled code here, we can just detect whether a value can be affected by side effects and refrain from reading it then. Since you can always explicitly reload a value that may have been changed, the resulting compile warnings are easily worked around in user code. Refactoring user code this way also makes it much clearer what is actually going on. Pick-to: 6.5 Task-number: QTBUG-109221 Change-Id: Ica832e39838ef732b0d181364630737fd7709b74 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Do not crash when converting number literals to enumsUlf Hermann2023-05-043-2/+8
| | | | | | | Amends commit 2a21efb5f7a6cac6f6101f2f42fe38f16dc68149. Change-Id: Id7d739b58c723eed9f165951b51ee2e5e55d7fe2 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QmlCompiler: Do not stop parsing on top-level Component elementsUlf Hermann2023-05-031-1/+0
| | | | | | | | | | | | | This just creates an inconsistent state where some of the document has been parsed and some hasn't. The only thing we actually need is the log message. Also, fix the warning message. Amends commit 169f0f71665a3a5155f8d63a9c11bc2484353561. Pick-to: 6.5 Fixes: QTBUG-112897 Change-Id: Ie8486909f9bea9ee1b87f2857f7b77fb7cc561e8 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QmlCompiler: Relax shadowing checkUlf Hermann2023-05-026-17/+90
| | | | | | | | | | | | | | | | | If we detect a property or method as potentially shadowed, we don't have to abandon all hope. We can still retrieve it as untyped var. Since there are a number of things we can do with untyped var, this may still be useful. In the same sense, we need to treat function calls as untyped when the function in question can be shadowed. Calling functions with var arguments and return types leads to some more interesting situations in the call frame setup, so we fix that, too. Task-number: QTBUG-112480 Change-Id: I238d1cf04951f390c73e14ed9e299f2aa72b68cb Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qqmldomastcreator: set qqmljsscope in DOM script elementsSami Shalayel2023-05-022-0/+10
| | | | | | | | | | | | Rename the getter from {setQ,q}QmlJSScope() to {setS,s}emanticScope(). Set the semantic scope in the script elements where needed. Test that BlockStatements contain their semantic scope. Task-number: QTBUG-100084 Task-number: QTBUG-111415 Change-Id: If8b34c7edaac6aaf42a1cb2c47b12820358709e5 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Inline some array methodsUlf Hermann2023-04-285-4/+266
| | | | | | | | | | | So far we can only deal with methods that don't change the source array and don't use iterators or functions as parameters. We also omit concat() for now. However, indexOf(), lastIndexOf(), includes(), join(), slice() and toString() are possible already now. Task-number: QTBUG-112722 Change-Id: Id19c74e8ad25af876bc954c040c767823b7e3259 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Remove emptyListTypeUlf Hermann2023-04-285-37/+4
| | | | | | | | | | | | It was a stop-gap solution on the way to actual list type support. It creates problems because it's a sequence type but doesn't have a value type. Add an assert to catch related problems earlier in the future. Fixes: QTBUG-113265 Change-Id: Iae955ab6c5ca41113095b523a5d6b9bcfd4d2396 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Use actual type of enums, rather than intUlf Hermann2023-04-265-28/+25
| | | | | | | | | | Now that the type is available from qmltypes we can just use it. Task-number: QTBUG-112180 Change-Id: I315372da0925f19c209f676226f450863b0d3ea5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QmlCompiler: Implement ConvertThisToObject and basic DTZUlf Hermann2023-04-255-9/+31
| | | | | | | | | | | | | | We know that 'this' is a QObject* since the metatypes stack frame mandates it. Whenever you pass 'this' to anything it's loaded from the special 'This' stack slot which then triggers a DTZ check. A DTZ check is a noop if we can prove that the type is statically known, though. In QmlCompiler, if we have a valid register content, then the register has been set in all code paths that lead to the instruction in question. Fixes: QTBUG-111439 Change-Id: I81d1cd140eea63f85628c3bef3a8f6db0a12096d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmltyperegistrar: Pass on type of enumsUlf Hermann2023-04-242-1/+7
| | | | | Change-Id: I1ee1efe31985b24923c024658adb2968dd2dfae2 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Recognize QStringList and QVariantList as special listsUlf Hermann2023-04-243-0/+25
| | | | | | | | | | They are equal to QList<QString> and QList<QVariant>, respectively. We cannot express this fact in qmltypes, but since those are builtin, we can just hardcode it. Task-number: QTBUG-112227 Change-Id: Iebeb5f6a5350d1c7184b1d9e6a38647e048c3806 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Allow conversion from QQmlListProperty to QListUlf Hermann2023-04-242-0/+13
| | | | | | | | | | In the happy case this just retrieves the internal QList from the list property. In the sad case it produces a deep copy. That's not worse than what the interpreter does, though. Fixes: QTBUG-112227 Change-Id: I8b2b0ac74c90b6dcee876e83a64502756733c1c5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Don't crash on bad list type in signatureUlf Hermann2023-04-191-2/+4
| | | | | | Pick-to: 6.5 Change-Id: I2c4a4ffa810258134a29b87aff46e8eb544b6a55 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Don't crash when checking for enum problemsUlf Hermann2023-04-192-6/+7
| | | | | | | | | When checking for CallProperty we want the call base, not the accumulator. Pick-to: 6.5 Change-Id: I24ac066dd440bde459e20b3cf962af04ca531629 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Fix content pointer check for QObject*Ulf Hermann2023-04-191-23/+35
| | | | | | | | | | | It can actually be null rather than undefined. We need to generate a separate check for that and output the correct error messages. Amends commit 05f56d7c78754855c643470ad4e8dfd35c96f927 Change-Id: Ia795e31805181640cd5be19359af51067d3fc8d6 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QmlCompiler: Merge bool and any pointer type into the pointer typeUlf Hermann2023-04-151-2/+2
| | | | | | | | | A pointer type can hold bool as either nullptr or some value. We don't need to produce a QVariant for that. Change-Id: I368c3fa703d08ff396a5b4702ba7d1f2614b1467 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QQmlSA: Remove dead codeFabian Kosmale2023-04-141-1/+0
| | | | | Change-Id: Iec9f607ead6ee32cc9bb1d40c5cd9967e86c7772 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* Dom: add QQmlJSScope to QmlObjectSami Shalayel2023-04-121-0/+13
| | | | | | | | | | | | | | | | | | | | | | | | | Add a flag that allows to construct the Dom with the QQmlJSScopes obtained by semantic analysis. Added a new AST visitor called QQmlDomAstCreatorWithQQmlJSScope. This visitor synchronizes the qqmldomastcreator and the qqmljsimportvisitor to construct the Dom and the QQmlJSScope from the AST at the same time. It mainly does keeping track which subvisitor (dom creator or scope creator) is active, as one subvisitor may visit AST nodes that the other does not. Using both visitors at the same time allows to insert the newly-generated QQmlJSScope::Ptr directly into the correct Dom structure. The actual implementation of QQmlDomAstCreatorWithQQmlJSScope is in its visitT and endVisitT methods. Both are called in the AST-visitor-overloads. Added a benchmark on two big generated qml files to see how fast/slow does the qqmljsccope semantic analysis runs, compared to the QmlDom creation runtime. Task-number: QTBUG-92876 Change-Id: Ia05b6fdd59a637fef9c14b6ab284f4550414f908 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QmlCompiler: Fix confused error messageUlf Hermann2023-04-031-3/+3
| | | | | | | | Amends commit aa4a1e96b8cdc5e6a5ea8e5e1c0406e9f496b92b. Pick-to: 6.5 Change-Id: Ia693e670dabc63d8c1034626ad57a89772ce4a6a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Support more integer typesUlf Hermann2023-03-304-111/+175
| | | | | | | | | | | This adds support for 8- and 16-bit signed and unsigned integer types. The test exposes that the engine fails to correctly convert out of range values when assigning to a 32-bit int property. Fix that as drive-by. Fixes: QTBUG-101634 Change-Id: I0a4177f49ffc062a1f444e30424e94c1f293e70c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* TypeResolver: Allow conversions from string to QDate and QTimeOlivier De Cannière2023-03-291-5/+3
| | | | | | | | The conversion from string to QDateTime is already possible. Change-Id: I1100065e424e3873c0723ad0359ed6d3d9984b5e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QmlCompiler: Simplify isRescricted checks down to only enumsOlivier De Cannière2023-03-224-53/+28
| | | | | | | | | | | | | Most checks in isRestricted were redundant. Only those related to enums seem to be useful. These are kept in the new checkForEnumProblems while isRestricted is removed. The error checking in checkForEnumProblems should also provide better error messages for enum problems. Pick-to: 6.5 Change-Id: Ic3f3589464ebe519bee8b4c580b2e80d310c937f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Guard against ID-lookup of value typesUlf Hermann2023-03-171-2/+17
| | | | | | | | Pick-to: 6.5 6.2 Task-number: QTBUG-111986 Change-Id: I10657e4176b5f57f3552728d8b2835e74b82bb60 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Do not generate invalid code on generate_AsUlf Hermann2023-03-171-4/+9
| | | | | | | Pick-to: 6.5 6.5.0 6.2 Task-number: QTBUG-111986 Change-Id: Ib6e7179c20e6c7a4d6fc3a1a17eac550d2bbfa56 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Don't needlessly generalize input on SetPropertyLookupUlf Hermann2023-03-171-2/+6
| | | | | | | | If we get a verbatim type as input there, we can just use it. Change-Id: If04c29c3756664718bf482a016f431cc5f26cee5 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QJSPrimitiveValue: Add data(), metaType() and a generic coercion methodUlf Hermann2023-03-172-25/+53
| | | | | | | This allows us to do some more specialized lookups in QmlCompiler. Change-Id: I7947c8e7bccfa57aee949b080a531a88fd47c8af Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Enforce sanity of type adjustments in basic blocks passUlf Hermann2023-03-115-26/+72
| | | | | | | | | | | | If we cannot properly adjust the types, the result will probably be garbage and we should not try to generate any code. We are double checking the actually received type in the code generator, but if we get a different type at code generation time than we "ordered" at type propagation time, that's not great. The type propagator should already have checked that the types are convertible, after all. Change-Id: I9c20dbd6b4cc8214e780dad9eb4302ca6ef81bac Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Fix logic in generate_As()Ulf Hermann2023-03-112-5/+7
| | | | | | | | | | | We want to communicate the input via the 'in' accumulator and the output via the 'out' accumulator, not the other way around. It would be a nice optimization to already read the input as the desired type, but since we only do QMetaObject::cast() and the "optional" Qvariant conversion for the "as" operation we cannot guarantee that the lhs can be read that way. Change-Id: I994e06a02c742ff375cf2edfaaf989adba7d6e90 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Allow coercing anything to boolUlf Hermann2023-03-102-0/+15
| | | | | | | JavaScript can coerce anything to bool, so should we. Change-Id: Id560e4c1dc10b5432c0cedf3110ad3377bbc5f59 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Use value type ctorsUlf Hermann2023-03-097-148/+273
| | | | | | | | | | | | | This allows us to do the relevant conversions in a more civilized way, dropping the outputVariantConversion() method. The latter is brittle because you have to manually add it to each instruction, and it uses QMetaType::convert() which is actually not guaranteed to give the same results as a QML type coercion. Task-number: QTBUG-94807 Change-Id: I4d6d05a60beb3b4dfc3da6f0142de25667510904 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Allow as-casting to value typesUlf Hermann2023-03-035-44/+239
| | | | | | | | | | | | | | | | | | | | | | If the "Addressable" option to ValueTypeBehavior is set, you can use the "as" operator to cast a previously unknown type into either undefined or the given type. We can use this in qmlcachegen to generate efficient code for further operations on the same type. In the generated C++ it in fact only works for GetLookup because: a, We generally don't do SetLookup on value types, yet. b, We generally don't call methods on value types, yet. c, We cannot store a union of undefined and a sequence type, yet. However, getting properties of value types is the most important application of the new casts so this is well worth it. As a side effect we can also look up things in potentially undefined results of other operations now. For example list lookups. Task-number: QTBUG-94807 Change-Id: Ifdf34f1f3f67b7a0a8953b9ed0e947b74638a28c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Add an "Addressable" value to ValueTypeBehaviorUlf Hermann2023-03-022-0/+8
| | | | | | | Task-number: QTBUG-94807 Change-Id: I8c78faa99fc4c4b2ffd8c89f1037fc7569212c73 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QmlCompiler: Improve method overload selectionUlf Hermann2023-03-021-9/+19
| | | | | | | | If we have an exact match we should definitely use that. Change-Id: I2846ecf6f9963a978b84b70fbe18acdfe6eb45e6 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Work around GCC 13 bogus warning about use-after-freeThiago Macieira2023-03-011-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | By simply adding std::move() to the variables we've received by value and aren't using again, thereby also improving performance slightly. The message was: In static member function ‘static void QSharedPointer<T>::deref(Data*) [with T = const QQmlJSScope]’, inlined from ‘void QSharedPointer<T>::deref() [with T = const QQmlJSScope]’ at qsharedpointer_impl.h:440:12, inlined from ‘QSharedPointer<T>::~QSharedPointer() [with T = const QQmlJSScope]’ at qsharedpointer_impl.h:280:30, inlined from ‘QDeferredSharedPointer<const QQmlJSScope>::~QDeferredSharedPointer()’ at qdeferredpointer_p.h:45:7, inlined from ‘QString QmltcCodeGenerator::generate_typeCount(Predicate, const InlineComponentOrDocumentRootName&) const cc1plus: error: pointer may be used after ‘void operator delete(void*)’ [-Werror=use-after-free] In static member function ‘static void QtSharedPointer::ExternalRefCountData::operator delete(void*)’, inlined from ‘static void QSharedPointer<T>::deref(Data*) [with T = const QQmlJSScope]’ at qsharedpointer_impl.h:448:13, inlined from ‘static void QSharedPointer<T>::deref(Data*) [with T = const QQmlJSScope]’ at qsharedpointer_impl.h:441:17, inlined from ‘void QSharedPointer<T>::deref() [with T = const QQmlJSScope]’ at qsharedpointer_impl.h:440:12, inlined from ‘QSharedPointer<T>::~QSharedPointer() [with T = const QQmlJSScope]’ at qsharedpointer_impl.h:280:30, inlined from ‘QDeferredSharedPointer<T>::operator QDeferredSharedPointer<const T>() const [with T = QQmlJSScope]’ at qdeferredpointer_p.h:75:83, inlined from ‘QString QmltcCodeGenerator::generate_typeCount(Predicate, const InlineComponentOrDocumentRootName&) const qsharedpointer_impl.h:130:67: note: call to ‘void operator delete(void*)’ here For reference: static void deref(Data *dd) noexcept { if (!dd) return; if (!dd->strongref.deref()) { dd->destroy(); } if (!dd->weakref.deref()) delete dd; } Note how there's one extra frame in the deletion sequence (QDeferredSharedPointer<T>::operator QDeferredSharedPointer<const T>()) compared to the use. The common source is if (t == visitor->result()) { // t is this document's root The variable `t` is a QDeferredSharedPointer<const QQmlJSScope>, but the right side is only QDeferredSharedPointer<QQmlJSScope>, which is why the conversion operator was called. operator QDeferredSharedPointer<const T>() const { return { m_data, m_factory }; } The above is calling the constructor QDeferredSharedPointer(QSharedPointer<T> data, QSharedPointer<Factory> factory) for T = const QQmlJSScope, which means it's calling template <class X, IfCompatible<X> = true> QSharedPointer(const QSharedPointer<X> &other) noexcept : value(other.value), d(other.d) to construct the const version from m_data. This temporary is then moved into the QDeferredSharedPointer's argument because it's a prvalue by way of QSharedPointer's move constructor QSharedPointer(QSharedPointer &&other) noexcept : value(other.value), d(other.d) { other.d = nullptr; other.value = nullptr; } After the QDeferredSharedPointer's constructor returns, the temporary QSharedPointer is destroyed, which is where the compiler saw the call to operator delete. Except that it can't happen. The move constructor will have set the temporary's d pointer to null, so when deref() is called on that temporary, the check will match: if (!dd) return; Pick-to: 6.4 6.5 Change-Id: I7f354474adce419ca6c2fffd17482074d5cdc9d5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QmlCompiler: Clarify code in StoreNameSloppyUlf Hermann2023-02-281-3/+1
| | | | | | | | In StoreNameSloppy we don't need to generalize the type in the way we have to do it in SetLookup. We can just throw whatever we got at it. Change-Id: I154abc31326c52f1f9ac07f26f67ba14a8b1bf24 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Drop broken line comments in generated C++Ulf Hermann2023-02-235-39/+6
| | | | | | | | | | | | | | | | | | They didn't work because the ordering of instructions is not the same as the ordering of lines. They also weren't very helpful because a single line may result in multiple instructions and vice versa. On top of everything, they also introduced UB via the std::upper_bound call. Rather, just print the name of the function and the place in the file at the beginning of each C++ function. That is much more helpful since we can then just correlate it to the original QML code. For instruction-by-instruction mapping we have to consult the byte code trace anyway. Pick-to: 6.5 6.4 6.2 Fixes: QTBUG-111340 Change-Id: I599ce384cfaf88a7347583a55976a3b98080435d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QmlCompiler: Implement multi-argument Math.{min,max}()Olivier De Cannière2023-02-231-8/+36
| | | | | | | | | | This patch extends the logic for the 2-argument Math.min() and Math.max() functions by reutilizing the same logic to compare two elements and evaluate all arguments with the current max or min. Fixes: QTBUG-108741 Change-Id: I993a26a1d44d66226c751272dfc2dc63330d115d Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QmlCompiler: Implement get lookup of variantMap propertiesOlivier De Cannière2023-02-224-11/+30
| | | | | | | | | | | | | | | | This patch adds support for get lookups of QVariantMap properties. Setting or modifying is not supported and will reject. Also, QQmlJSRegisterContent::JavaScriptObjectProperty was renamed to QQmlJSRegisterContent::GenericObjectProperty Tests were added to TestQmllint::cleanQmlCode() and tst_QmlCppCodegen::variantMapLookup(). Pick-to: 6.5 Fixes: QTBUG-105545 Change-Id: I653ee4e7de1fb1514e1e563a92cfc28633268a7e Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QML: Allow pragmas with multiple valuesUlf Hermann2023-02-221-29/+48
| | | | | | | | | This will be needed in follow-up changes. Task-number: QTBUG-94807 Change-Id: I6243ea31290251c30dd0aceaae878568bc1c0525 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QmlCompiler: Fix coercion of undefined to float and doubleUlf Hermann2023-02-211-7/+11
| | | | | | | | | | | | | | | | It should result in NaN, not in 0. The typedArray() test exposes that ExecutionEngine::toVariant() also gets this wrong. Fix that, too. [ChangeLog][QtQml][Important Behavior Changes] Converting a JavaScript value to a double or float, for example by inserting it into a typed array, now assumes JavaScript type coercion semantics. In particular, converting a value that is not actually a number now results in NaN where it previously sometimes resulted in 0. Pick-to: 6.5 6.4 6.2 Fixes: QTBUG-111179 Change-Id: If24444ae9014c8972761c565a6920f06699e485c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>