Commit Graph

261 Commits

Author SHA1 Message Date
Ulf Hermann 9035d1cb2a QmlCompiler: Restore support for writing to temporary arrays
We use the JavaScript extension as "read" type to signify that the code
generator will accept any type with such an extension. This requires
some adjustments in the type resolver.

Pick-to: 6.10 6.9 6.8 6.5
Task-number: QTBUG-137540
Change-Id: Ia34ca0a24c417c5372852268ba2f55825484639d
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2025-06-23 11:17:06 +02:00
Olivier De Cannière a35b0e44ae Qml: Allow accessing unscoped enums values as <Component>.<Enum>.<Key>
[ChangeLog][QML] It is now possible to access unscoped enum values in a
scoped way as <component name>.<enum name>.<key>. Previously, it was
only possible to access them in an unscoped way.

Task-number: QTBUG-116513
Change-Id: Iff56cd3365516215e1e195a147fae66ee17d39e3
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2025-05-31 10:36:42 +02:00
Olivier De Cannière f4c2eeac6a Compiler: Deduplicate conversion origins based on register's content
In the type propagator, when encountering back jumps, we need to run the
pass again in order to ensure that the state of the registers at the
target of the jump is fully known.

For this, we need to compare the latest state in the current pass with
states we have encountered earlier. If a match is found, no more passes
are needed.

The propagation is run multiple times and state is accumulated between
passes. For certain conversions, this will try to append types as
origins again every iteration. These would previously have been
deduplicated by QQmlJSTypeResolver::merge but, since the change at
1e095058e1, we consider 2 registers to be
equal only if their d pointers are equal. And since instructions such as
MoveRegexp create a new register for the literal type RegExpr every
time, the pointer doesn't match with the one from the register created
by the instruction during the ealier pass. This would lead to set of
origin types growing forever and to the state never matching a previous
one. This, in turn, caused an infinite loop because an additional pass
was always deemed necessary.

Therefore, restore the old logic that deduplicates based on contained
type, variant, and (recursively) scope.

Amends 1e095058e1

Fixes: QTBUG-135457
Pick-to: 6.9
Change-Id: I23167e95b958304698d12537598c1d72b03a5364
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2025-05-01 19:19:22 +02:00
Olivier De Cannière b5e586f984 Compiler: Skip bindings to properties of type QQmlScriptString
There is nothing to do in the compiler.

Setting the value of the property is already handled in by the object
creator or the qobjectwrapper.

Reading the value doesn't really makes sense and defeats its purpose .

Fixes: QTBUG-134790
Pick-to: 6.9 6.8
Change-Id: I4576eb528e0dec273830b0244149a92ceb325bc9
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2025-04-17 12:10:22 +02:00
Ulf Hermann 0bd329a0b4 QmlCompiler: Error out on unstorable types
We already do this for return types, but it's fatal on any type.

Pick-to: 6.9
Fixes: QTBUG-135342
Change-Id: I7aee2a19ffcd39d2707eceb34b5073057d8b5ebb
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2025-04-14 11:29:35 +02:00
Olivier De Cannière 5ff76ab872 Compiler: Use regular lookup for redundant optional lookups
If we can determine that the base of an optional lookup cannot hold null
or undefined, we can simply omit the optional part and generate a
regular get lookup. This is also true whenever we lookup an enum.

Amends fc4ee77116

Fixes: QTBUG-135649
Pick-to: 6.9 6.8
Change-Id: I64984fdecc75cd4dbc2274a08aa73b5274fb09b7
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2025-04-10 13:35:00 +02:00
Ulf Hermann c36416c971 QmlCompiler: Do not re-resolve iterator value types
We've resolved the value type in the type propagator. Trying to do it
again in the code generator, after the iterator may have been adjusted,
is quite wrong. If we resolve the list value type on a type that's not
a list (anymore), then we get an invalid type, which subsequently
crashes.

Amends commit a173d50a9e.

Pick-to: 6.9 6.8
Fixes: QTBUG-135288
Change-Id: I1227803ed100c83f8fc11898be0a4d0199d639dd
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2025-03-31 08:29:52 +00:00
Olivier De Cannière 2cc30828af QML: Add final property attribute
This works the same as the FINAL attribute to Q_PROPERTY.

Task-number: QTBUG-98320
Change-Id: Icc2cf1afb5354fd711770f7147ded853b74cd1da
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2025-03-06 19:23:04 +01:00
Ulf Hermann d9d1c1fb5e QtQml: Support url and date in 'instanceof' and 'as'
Those have several possible representations. Besides
QQmlValueTypeWrapper, they can also be their own special heap objects
with extra methods, or VariantObject.

Also, remove some pointless restrictions in QmlCompiler that prevented
such as-casts from being compiled to C++. The code generator will
currently reject non-trivial type assertions for value types. Therefore
we don't have to take care of ValueTypeBehavior: Assertable, yet.

Also fix tst_qqmllanguage::instanceOf() to actually test something. So
far the return value of the expression was ignored for most data tags.

Pick-to: 6.9
Fixes: QTBUG-130291
Change-Id: I2facf48455a04a02a078615e5ebd4b1c26d1bd93
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2025-02-28 20:11:32 +01:00
Ulf Hermann f7e29f7d27 QtQml: Clean up qmldir redirection
We need to perform the redirection before inserting imports into
namespaces. Through the redirection we might discover a module that we
have already imported before. In that case we must not import it again.

Pick-to: 6.9 6.8
Fixes: QTBUG-133587
Change-Id: I47a279461763b5397137002a9e7c7d3bfc7ad15d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2025-02-26 20:54:39 +01:00
Ulf Hermann 7d510cfc0b QtQml: Fix AOT compiled context for destroy() and toString() methods
Those are not mapped to regular QMetaMethods but rather come with
special method indices and need to be resolved separately.

Amends commit a741271dd5

This exposes that the override order between JavaScript extensions and
their base types was wrong. JavaScript extensions do certainly not
override their base types. Fix this, too.

We also need to always specialize the lookups for these calls. It
doesn't actually matter if there is propertyData or not since we branch
off into the special cases anyway when calling them.

Pick-to: 6.9
Fixes: QTBUG-132602
Change-Id: Iea83ce94459b0d0a3bf54731898fd62b9ad46c46
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2025-02-26 20:54:39 +01:00
Ulf Hermann a5cb71925c QmlCompiler: Tighten detection of assignment to unknown properties
While those properties may be of type Component, they don't have to. We
can in fact not resolve anything resembling an ID while inside one of
those objects because we cannot determine the component boundaries.

Amends commit dea8e38d95

Pick-to: 6.9 6.8
Fixes: QTBUG-133460
Change-Id: Iac7294166d38ce591c45c0d31b139a52eda70fc1
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2025-02-21 16:20:38 +01:00
Ulf Hermann f9fbe137c7 QmlCompiler: Extend the listConversion test
The actual conversion code suggests that we may be creating a shared
list property. However, the assignment code internally won't let that
happen. Test as much.

Amends commit 3108c58b97

Task-number: QTBUG-133047
Change-Id: I66f0f043e0dabd2693aa50a30478461a5db5c5ad
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2025-02-19 12:40:20 +01:00
Ulf Hermann 7139e893d0 QmlCompiler: Only import hardcoded builtins by default
At run time, not all the builtins are always available, but only those
hardcoded into the parser. If we always import all the builtins at
compile time, we introduce subtle errors when they shadow parts of the
JavaScript global object.

Now the builtins need to be actually imported. We cannot rely on the
magic that adds them to the root scope of each document anymore. To this
end, they need to become a regular module.

The builtins are now loaded using a qmldir, just like any other module.
The only thing special about is its "system" attribute which we now
take to mean "read jsroot.qmltypes". Furthermore, the builtins get a
"static" attribute so that we don't warn about them being unused. Even
though they can now technically be unused, we really want people to
still import them.

Pick-to: 6.9 6.8
Fixes: QTBUG-133461
Change-Id: I322e14ba85c939773d36143ca24e88a7c9db23f5
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2025-02-18 22:43:53 +00:00
Olivier De Cannière 73227258b0 Compiler: Add missing conversion for variant equality comparisons
The comparison code was generated properly but the conversion to safely
assign the result of the comparison to the out accumulator was missing.

Amends 78b58582ba

Fixes: QTBUG-133636
Pick-to: 6.9 6.8
Change-Id: I9f790b449b48c382064954ad4235d25d221f1168
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2025-02-18 20:02:02 +01:00
Ulf Hermann 3108c58b97 QtQml: Add conversion code for QQmlListProperty to other lists
We have the same conversion code already for lists of value types and
JavaScript arrays. Specialize the common cases of QObjectList and
QQmlListProperty<QObject>.

Pick-to: 6.9 6.8
Fixes: QTBUG-133047
Change-Id: I10826d4a965e18471a486e19befef961ec9a4a6e
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2025-01-24 20:30:23 +01:00
Ulf Hermann 0f0f0adc51 QtQml: Check 'this' for null in callObjectPropertyLookup
Before the refactoring of callObjectPropertyLookup and
initCallObjectPropertyLookup this was done via a check on the resulting
function. This check is in the init method now. However, after
initialization, you can still call the (pre-resolved) method on a nullptr.
Therefore, we need a second check.

The method counts as pre-resolved even if we re-fetch it due to a
variant lookup. We can be sure that there is some method in that case
after all.

Amends commit a741271dd5

Pick-to: 6.9
Fixes: QTBUG-132499
Change-Id: Idb8c50f3698c5502cf2e8116e6341ef1a537bc64
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2025-01-06 17:27:59 +01:00
Ulf Hermann 78ccc84dde QtQml: Do not crash when loading .js files as QML
Pick-to: 6.9 6.8 6.5
Fixes: QTBUG-132118
Change-Id: Id5f680b3dfe1118c3af7cf32d1da7492119a4e51
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2025-01-06 17:27:52 +01:00
Ulf Hermann 735556d19d QtQml: Accept .js and .mjs files in directory-listing qmldirs
Since it's documented like this, we should actually allow it.

Pick-to: 6.9 6.8 6.5
Task-number: QTBUG-132118
Change-Id: I2192f040b8fdf545b8dbb0687b6e618a9858ed07
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2025-01-06 17:27:47 +01:00
Ulf Hermann daab238846 QmlCompiler: Round towards 0 when coercing to 64bit integers
The regular int32 coercion doesn't apply here. We have our own logic for
this case.

Pick-to: 6.9 6.8
Task-number: QTBUG-132345
Change-Id: I96596567ce83fcaa714c8372171261e8dd876480
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-12-20 09:44:16 +01:00
Ulf Hermann 70d9a5cbcd QmlCompiler: Name types when initializing structured value types
The conversion is not required to produce the same type. It can also
produce something equivalent that holds the same value. For example an
integer of a different kind that on assignment gets C++-converted.

Pick-to: 6.9 6.8
Task-number: QTBUG-132345
Change-Id: I07accb38062b7c89ab60d50bf6cbd63423e68301
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-12-19 12:39:38 +01:00
Ulf Hermann 38d65db7ae QmlCompiler: Drop the type shuffling on SetLookup
It's not necessary anymore. We can use the read register as-is. Also,
explicitly name the type we are going to use to avoid integer range
mismatches on coercion.

Pick-to: 6.9 6.8
Task-number: QTBUG-132345
Change-Id: I98d246b03e5194235246ee8e4ebcb0a8e0094a5b
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-12-19 12:39:38 +01:00
Ulf Hermann 3d12a83170 QmlCompiler: Coerce values when calling methods
The type of the register may not be the one to be passed to the method.
We cannot rely on the run time internals to coerce the value anymore
since we've moved the type determination out of the generated code.

To make this happen, we need to adjust the storage types of read
registers in the storage generalizer.

Pick-to: 6.9
Fixes: QTBUG-132329
Change-Id: I642027f349f7c05f714ec36ef4e23f9d59b4a8df
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-12-19 12:39:38 +01:00
Tor Arne Vestbø ae7a573fe9 Compute implicitSize based on implicitContentSize in Pane and subclasses
Now that Pane reflects its explicitly set contentWidth/Height through
implicitContentWidth/Height we can use the same expression for implicit
width/height as regular controls, which hooks us into the safe area
binding loop detection as well.

Pick-to: 6.9
Change-Id: Ie31b740a1e405341fc5f0ed9673b213292e4afd9
Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
2024-12-18 20:37:27 +01:00
Ulf Hermann 94a481d433 QmlCompiler: Use correct static_metacall on DefineObjectLiteral
When constructing a value type, we cannot just assume that the
most-derived type holds all the properties. We may encounter properties
from base types. Resolve those via QMetaProperty.

Pick-to: 6.9 6.8
Fixes: QTBUG-131980
Change-Id: I8e1773ccb42f86b96457c990ae5bc6486ae1acdc
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-12-12 18:20:55 +01:00
Ulf Hermann bf7261d67d QmlCompiler: Implement calling of methods on value types
Define a pair of lookup methods for this and generate code that uses
them. Write back after calling a non-const method.

Task-number: QTBUG-127174
Change-Id: I6de22e76b63390fd7159d9c14ea2c908d961ec97
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-11-22 17:39:29 +01:00
Ulf Hermann 7ed5f038fc QmlCompiler: Add AsVariant initializations for SetLookup
With SetLookup there is always the possibility of causing a reset by
passing undefined. That's why we need to wrap the argument into QVariant
most of the time. SetValueLookup didn't take this into account, which
resulted in invalid code.

The test also reveals that a number of cases were generating different
errors depending on whether the code was run in interpreted or compiled
mode. Align those.

Pick-to: 6.8
Task-number: QTBUG-127174
Change-Id: I88f45977dcd0eeba8aaf580663d4b85b8bb26f72
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2024-11-21 15:25:56 +01:00
Ulf Hermann 12fb7d2743 QtQml: Fix calling of method with QML_USING types
On the engine side, types made available with QML_USING are recognizable
by their QMetaType conversions. In order to actually call the right
methods, we need to slightly prefer methods to whose arguments we can
convert over ones we have not idea about. This, however, adds the
problem of converting to QString, double, QVariant and QJSValue, which
is possible for any type. Since such conversions are less specific than
manually added converters, we de-prioritize them a bit.

On the compiler side we need to transmit the knowledge about the
overload to be called from the compiler (which has already done its own
overload selection) to the lookup methods. This is easily done using the
relative method index. This way we do not need to do any run time
overload selection at all and we do not need to pass any types to the
lookup methods. We can do this without further compatibility adaptations
because the current version of those lookup methods was only introduced
in 6.9.

Excluded, of course, are shadowable calls, which are performed with only
QVariant arguments. These carry the arguments themselves and trigger the
engine's overload selection. Internally nothing changes about them.
Passing a list of QMetaType::fromType<QVariant>() to the lookup methods
for them has always been a waste.

Only the engine changes are relevant for 6.8. In 6.8, the lookup methods
defer the overload selection to the engine and take the types on every
call. We still cannot separate the engine changes from the compiler
changes in dev because the same test is run once in interpreted and once
in compiled mode.

Pick-to: 6.8
Task-number: QTBUG-127174
Change-Id: I6ab52ddf3be65dcc94547266c5dcc5ac1050c93c
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-11-13 11:58:50 +01:00
Ulf Hermann 80c6d3c08b QtQml: Never check the type in AOT lookup initializations
qmlcachegen will never generate code that calls these with mismatched
types. Checking the type at run time is wasteful. With QML_USING, you
can make qmlcachegen generate code with types we cannot recognize as
compatible. However, those need to be layout-compatible so that they
can be reinterpret_cast'ed into each other. If they aren't that's a user
error in C++. We can crash on such a thing.

However, in StoreNameSloppy and in the variant lookup cases, we do need
to convert types. Since the QML_USING type conversions are unknown to
the QML engine, we have to provide a fallback via QMetaType::convert()
here. So, despite the layout compatibility requirement, the QML_USING
types also need to register metatype converters before any QML code
accesses them.

As a result QML_USING has quite a few complicated requirements now and
is _really_ dangerous.

Pick-to: 6.8
Task-number: QTBUG-127174
Change-Id: I1b8e1595e3088415ce711e910586a5dd456cb2c5
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-11-12 08:46:32 +01:00
Ulf Hermann 05b783617f QmlCompiler: Support construction of value types with 'new'
This allows us to create value types with invokable copy ctors from
JavaScript objects that describe their properties. That way we now have
a full replacement for the Qt.foo() methods.

As a side effect, we support retrieval of enums for certain kinds of
broken value types now, if prefixed with a namespace.

Fixes: QTBUG-124634
Change-Id: If2a3c59d647e211ef5a0cd1ddee04b409d9ea5f3
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-11-06 10:00:07 +01:00
Ulf Hermann 5b867e3548 QmlCompiler: Allow conversion of object literals to QJSValue
Task-number: QTBUG-124634
Change-Id: Ifb09c0f5e4a732518e44a8d3b73c5a836ad66508
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-11-01 12:52:03 +01:00
Ulf Hermann 35630eef3d QtQml: Unify detaching behavior for all reference objects
All reference objects should be detached when written to a property of
a QML-defined type. This is in line with what happens if you write the
same object to a property of a C++-defined type and doing anything else
makes very little sense.

In particular, before this change, the behavior differed between
ahead-of-time compiled code and interpreted code, between writing to
"var" properties and writing to typed properties, and between different
kinds of lists. Now everything we recognize as reference object always
gets detached when writing to a property.

[ChangeLog][QtQml][Important Behavior Changes] Writing a list or value
type to a QML-declared property now always detaches this same list or
value from any locals or other properties you may have read it from.
Therefore, subsequent changes to its "source" will not affect it
anymore. This is in line with what we do to C++-declared properties.

Fixes: QTBUG-127957
Change-Id: Icdf188ef29d28e5d3aaa8219cc003e07e8813f38
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-10-24 18:27:03 +00:00
Ulf Hermann 46795bcfaa tst_qmlcppcodegen: Prevent crashes on failure
You can QCOMPARE a QString to a unicode literal, but if the comparison
fails, it cannot print the result.

Change-Id: Iceea7074ecb893bc0c514d3b872e33b786edac84
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2024-10-24 14:19:24 +02:00
Ulf Hermann a741271dd5 QmlCompiler: Resolve types for calls in init step
Now that resolving the types can be more expensive, especially for
composite types, we should be careful not to do it too often. Most of
the cases where we have to resolve types are for lookups. Most of the
lookups only resolve types in their "init" step, which ideally is only
performed once in the application life time.

However, so far calls had to pass the types of arguments and return
values in the actual "lookup" step, which causes the resolution to
happen on every call.

This change moves those type resolutions to the init step. We can do
this because:

1. Regular typed method calls are calls to a specific overload with
   specific types. The method itself already has the list of types and
   we can just remember which one that is. Then we don't need to pass
   the types.

2. Calls to shadowable methods are all-QVariant typed. The only thing
   we need to know is the number of arguments. Then we can construct
   the list of types in the lookup itself.

We can remember which one of those we're dealing with by adding further
"AsVariant" lookup functions. For the case of non-property-cached
regular methods we also need a new "Fallback" lookup like we already
have it for properties.

Change-Id: I74a3729131d6a5ea0ad79e276965a5167cd609be
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2024-10-14 17:10:45 +02:00
Olivier De Cannière 349a180967 tst_qmlcppcodegen: Compile test with QT_NO_CAST_FROM_ASCII
This should help find raw string literals in generated code

Task-number: QTBUG-129797
Change-Id: I66e5d6302319678b494030e8cb3459eb06f0f134
Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
2024-10-09 16:23:14 +02:00
Ulf Hermann a5a814d26a QmlCompiler: Fix handling of anonymous composite types
So far we produced invalid QMetaTypes for them in various places and
that "worked" for the most part because with QObject pointers we can
introspect the actual type at run time.

Realize that we never actually want the concrete anoymous type of the
object when we pass it around. Rather, all methods and properties need
to handle named types. What we really want to resolve is therefore not
the type of the original value we've produced in the type propagator,
but rather the replacement we've produced when analyzing the lookup.

Pick-to: 6.8
Task-number: QTBUG-129202
Change-Id: I0b93495d6603f120375048c80a747170f147f8af
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
(cherry picked from commit 14ff6822a0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-10-02 08:46:46 +00:00
Ulf Hermann 76ce5e4799 QmlCompiler: Do not cache composite metatypes in static members
The metatypes from any old engines may have been deleted.

Retrieve the types from the ResolveTypeReferenceMap instead. That is
much cheaper than doing a full type search and the CU should know the
types it's dealing with.

Sometimes, however, the CU does not pre-resolve the types. In
particular, types only used in function signatures do not end up in the
ResolvedTypeReferenceMap. In those cases, still do the full type search.

Amends commit 8bf5aae19b.

Pick-to: 6.8.0 6.8
Task-number: QTBUG-129388
Change-Id: I27f25e1c68de3c752d00345c6d94016fb315e16c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-09-30 20:26:35 +02:00
Ulf Hermann dea8e38d95 QmlCompiler: Do not miscompile ID lookups in invalid types
If we cannot resolve a type, we need to assume that all its properties
are components and assign separate contexts to all inner objects.
Otherwise, if one of them actually is, the attempt to resolve it at run
time will crash.

Pick-to: 6.8
Fixes: QTBUG-129281
Change-Id: Ic34b5308accdd93f6797ee39fcd56040cf86b1ce
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-09-25 21:24:12 +02:00
Ulf Hermann bfd80e8dac QmlCompiler: Don't crash on broken type assertions
If we cannot properly resolve the types we should still set the
accumulator to something so that the type propagator can continue.

Amends commit 6a2308e500

Change-Id: Idf3d093ca877bcf11f6a9a82a9d01ccead19e2cc
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-09-25 10:42:01 +02:00
Ulf Hermann 815965f8fc QtQml: Allow initialization of value types with object types
If the value type has a suitable ctor, we can pass it a pointer to the
object just created.

Change-Id: I146c7dfc4f879ceb26201511d1c3b4127ad90dbe
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Varanka <sami.varanka@qt.io>
2024-09-24 13:58:33 +02:00
Ulf Hermann 9f554ef8cf QmlCompiler: Do not choose unstorable stored types
In order to pass the argument to a value type ctor we need to store it
in something we can rely on.

Amends commmit dd731b880b

Change-Id: I5d1ef6b4611aad9b595235f4f874ef4a063f04c6
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-08-12 16:19:40 +02:00
Sami Shalayel 45c21c39f0 qmllint/quick: rename attached type warnings to be uniform
Rename runtime warnings and qmllint warnings to be uniform, instead of
having many different formulations for the same problem.
This makes it easier to document them, at least for the qmllint warning
documentation.

Pick-to: 6.7 6.8
Task-number: QTBUG-118112
Change-Id: Iabb3a5fb0679523764b9f2fe2d99f4eb93a13c88
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-08-08 11:39:33 +02:00
Olivier De Cannière 179581e16f Compiler: Properly read value type arguments when enforcing signatures
The patch that introduces the enforcing of signature types did so by
passing the contained rather than the stored metatypes for the
arguments.

These types are used to populate the registers of the function with the
arguments using the proper types by static_cast'ing the void* arguments
to the actual types.

However, for value types, the arguments were assumed to be QVariants and
were thus casted to one even though they were actually passed as the
actual argument type. This seems to have been mostly fine by accident
because of the inline storage of QVariant that lays at offset 0 in its
layout. Therefore, if the flag signalling that the value is actually
elsewhere was not set to 1 by the casting and the value fit in the
inline storage everything would still work. This is not always the case
however and can lead to crashes.

Therefore, treat value type arguments as plain non-wrapped values when
populating function arguments.

Amends 8bf5aae19b

Fixes: QTBUG-127009
Pick-to: 6.8
Change-Id: I495bcff7631399f207d87fea698d7e921e8e4721
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-07-17 12:14:46 +02:00
Ulf Hermann f2431370ad QML: Allow conversion between different list types
We universally allow this pretty much everywhere else. We should also
allow it when evaluating bindings. To facilitate this, generalize the
SequencePrototype::toVariant() method so that it works with any
array-like and faithfully coerces the elements by the type coercion
rules.

Pick-to: 6.8
Fixes: QTBUG-126398
Change-Id: I520cd40e5f74bee5ac4b418aa86dc043774efcbe
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-07-03 16:36:49 +02:00
Ulf Hermann ae76c8f428 QmlCompiler: Fix side effect detection for array methods
Array methods that manipulate the array they are called on always have
side effects, on that array. In order to optimize them out we'd have to
do some more involved tracking of affected values.

Amends commit e846864151

Fixes: QTBUG-126834
Pick-to: 6.8 6.7
Change-Id: Ia4395ea21e89590e6ffe95e236f70b5e64402f5e
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-07-02 21:16:21 +02:00
Ulf Hermann 3d3ff946e3 QmlCompiler: Don't generate invalid code for unstorable lists
When printing a sequence type through one of the console methods, we
have to consider the adjusted type, not only the one we intended to
read.

Amends commit 7894f271ab.

Pick-to: 6.8
Task-number: QTBUG-126398
Change-Id: I4606ed2006a547bdf93ec136ebbfab10b706b917
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-06-28 18:16:48 +02:00
Ulf Hermann ed61e7c6d2 QmlCompiler: Explicitly cast operations that result in QString
We may be using QStringBuilder, and that can be stored in QVariant (and
possibly other places).

Fixes: QTBUG-125576
Change-Id: Ib31e31591a3333e51f1d5594ee05fdb8f0744714
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-05-25 08:11:24 +02:00
Ulf Hermann 8bf5aae19b QtQml: Properly enforce signatures of AOT-compiled functions
Pass the metatypes of the contained types rather than the stored types.

[ChangeLog][QtQml][Important Behavior Changes] The AOT compiled code for
type-annotated JavaScript functions does not let you pass or return
values of the wrong type anymore.

Fixes: QTBUG-119885
Change-Id: I685d398c0745d32a999a3abd76c622a2c0d6651f
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-04-26 12:18:15 +00:00
Luca Di Sera bd6df61c81 qmlsc: Support Math static properties
The javascript Math object presents some static properties that allow
access to some general mathematical constants.

Currently, `qmlsc` will refuse to generate optimized code for those
properties when used in a binding, for example given:

```
import QtQuick

Window {
    width: 200 * Math.PI
}

```

`qmlsc` will report a warning and will not generate code for the "width"
binding.

To allow `qmlsc` to generate optimized code for such cases, the handling
of `Math` related properties lookups is now specialized.

`QQmlJSTypePropagator::propagatePropertyLookup`, which is called when
dealing with an access such as `Math.PI`, was modified to consider the
result type a "double" when dealing with properties on the `Math`
object.

`QQmlJSCodeGenerator::generate_GetLookupHelper`, which generates the
code that provides a value for the property access, was modified to
special case lookups on the `Math` object.

If a property is being looked up on the `Math` object, `qmlsc` will now
generate a direct assignment for the output variable to a constant value
that is suitable for the accessed property.

A test was added to ensure that the snippet from the bug-report now
compiles without warnings.

A test was added to ensure that the properties from the Math global
object have an approximately correct value.

Fixes: QTBUG-113150
Change-Id: I8903794fc8ce2b55532a4706e1bda07a7b73f311
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2024-04-18 22:30:24 +02:00
Ulf Hermann 7894f271ab QmlCompiler: Allow coercion of lists to strings
We have to allow two different forms of coercion. When printing directly
through console.log etc, we add a pair of square brackets around the
string.

Fixes: QTBUG-119482
Change-Id: I03177e5905b41f5f0b5aaa867b18379eb9c7a243
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-04-11 13:47:46 +00:00