Commit Graph

197 Commits

Author SHA1 Message Date
Olivier De Cannière 15b1aaadd2 Compiler: Also check for shadowing on optional lookups
Amends: fc4ee77116

Pick-to: 6.7
Change-Id: I3f5f2b74e4b89b82e7fb54072091143010bab8aa
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-02-08 10:17:33 +01:00
Olivier De Cannière 72308ce207 Compiler: Convert from stored to original type when generating equality
Pick-to: 6.7
Fixes: QTBUG-121909
Change-Id: I913f59324364052d7893d4c4072f92fcf418a388
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2024-02-07 17:23:01 +01:00
Ulf Hermann 452929cea1 QmlCompiler: Reject lookups on shadowable base types
If the base type of a lookup is shadowable we cannot give any guarantees
at all about what is going to happen. Only if the right hand side of the
lookup is shadowable we can use our QVariant trick.

Fixes: QTBUG-121734
Pick-to: 6.7 6.6
Change-Id: I969a842a6bc6d6a4446bfbfb50f1a7021b84049e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2024-02-01 09:33:09 +01:00
Olivier De Cannière 3672a173df Compiler: Don't crash on optional lookups on QJSValue base type
Handle the case where the base type of the lookup is QJSValue so that we
don't hit the assert.

However, it should not be possible to get a QJSValue there at all. This
should be investigated further. Created QTBUG-121662.

Pick-to: 6.7
Fixes: QTBUG-121393
Change-Id: I8bea87cbff74119bb977635ec391601f47269ff0
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2024-01-29 17:02:28 +01:00
Ulf Hermann afbf7b6990 QmlCompiler: Handle non-resettable undefined assignment
We need to generate an exception if undefined is assigned to a property
that can't be reset. We don't want to reject everything that can
potentially be undefined. Therefore, we use the QVariant fallback and
examine the value for undefined at run time.

Pick-to: 6.7 6.6 6.5 6.2
Change-Id: I0a034032f4522f017b452690d93319eb4bfedb1c
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-01-25 18:35:05 +01:00
Ulf Hermann da6680cb2e QmlCompiler: Implement resetting of properties
We piggy-back on the mechanism used to handle shadowable properties and
pass the value as QVariant. QVariant can hold undefined and the lookup
functions know how to handle it.

Pick-to: 6.7 6.6 6.5 6.2
Fixes: QTBUG-120512
Change-Id: I9bca4940256c82bdcf5540b956600eb420be363e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-01-25 18:35:05 +01:00
Ulf Hermann be481412cc QmlCompiler: Allow primitive conversion if output is stored in var
We can always convertStored() if the contained type has been fixed.

Pick-to: 6.7
Fixes: QTBUG-120322
Change-Id: I7d834fa32a12503341c863c095d578ca6e838531
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-01-11 00:42:17 +01:00
Olivier De Cannière 6f74f50fe4 Compiler: Handle all integer signs and sizes when converting primitives
Fixes: QTBUG-120473
Pick-to: 6.7
Change-Id: I4941cd1567d94823551e4cc94df8bc5b413e951c
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2024-01-09 10:40:49 +01:00
Olivier De Cannière 22d4a1b795 Compiler: Guard against null dereference when ignoring function return
When a function is called, two arrays with the necessary information are
passed to the engine:
  argv:  [return address, prameter 1 address, parameter 2 address, ...]
  types: [return type, parameter 1 type, parameter 2 type, ...]

When the result of the call is ignored, the return type is set to void
and the return address to null.

A check for this null value was missing leading to a null derefence.

Amends: 4f1b9156a4

Fixes: QTBUG-120336
Pick-to: 6.7
Change-Id: I4a21779f3276b0143087b41b0d16c0cd3ba0e7db
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2024-01-09 10:40:49 +01:00
Ulf Hermann 49ea766c8f QmlCompiler: Return early after reject()
Otherwise we can run into an infinite loop.

Pick-to: 6.7
Fixes: QTBUG-120322
Change-Id: I81f9402beb48faf09b4fe148271d4347b84ddc5e
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2023-12-22 09:50:35 +01:00
Ulf Hermann 87d27d0654 QML: Don't crash when calling coerceAndCall() with null thisObject
Pick-to: 6.6 6.5
Fixes: QTBUG-119395
Change-Id: I5877beef9a53d358a6f58f9ce5029688bd9dcedb
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-12-08 20:11:28 +01:00
Ulf Hermann c89c14423b QmlCompiler: Preferably wrap types in QJSPrimitiveValue for SetLookup
If we store one primitive type inside another, we cannot get its content
pointer.

Change-Id: I7088685fdd2633085de732aab87b4b5f93300b90
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-12-08 20:11:27 +01:00
Ulf Hermann 78b58582ba QmlCompiler: Add generic QVariant-to-typed comparison
Since we have a lot more shadowable values now, we need to add this.

Change-Id: Ie9f389730bb6f330b1cd28f9229c5dd143727e4f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-12-07 13:29:41 +01:00
Ulf Hermann 9f8193b65b QmlCompiler: Do not adjust renames
A rename always produces a register with exactly one tracked type, but
we do not want to use it as base for the type adjustments. We want to
adjust based on the original location and its readers (which includes
any renames).

Pick-to: 6.6 6.5
Change-Id: Iaefdf56992c7c101a35a056fb93c49ade5ccf393
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2023-12-07 12:54:37 +01:00
Ulf Hermann 6b39eb9be2 QML: Use actual type for aliases of enum values
The metatype system and the compiler may disagree about the underlying
type. It's generally better to pass the full type information. We can
deal with it everywhere by now.

Amends commit 3ea55bf398

Pick-to: 6.6
Fixes: QTBUG-119531
Change-Id: I4744f5fb81fb5430ac040ec5877f7d0845a2ab12
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-12-05 12:50:59 +01:00
Ulf Hermann 84d950bc32 QML: Let IDs in outer context override bound components' properties
This is necessary to make the usage of such IDs actually safe. If we let
local properties override outer IDs, then adding local properties in
later versions invalidates the ID lookups.

[ChangeLog][QtQml][Important Behavior Changes] In QML documents with
bound components, IDs defined in outer contexts override properties
defined in inner contexts now. This is how qmlcachegen has always
interpreted bound components when generating C++ code, and it is
required to make access to outer IDs actually safe. The interpreter and
JIT have previously preferred inner properties over outer IDs.

Pick-to: 6.6 6.5
Fixes: QTBUG-119162
Change-Id: Ic5d3cc3342b4518d3fde1b800efe1b95d8e8b210
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-12-04 15:19:09 +01:00
Olivier De Cannière fc4ee77116 Compiler: Add initial support for optional chaining
This patch implements the GetOptionalLookup instruction in the compiler.
This enables the use of optional chains.

Fixes: QTBUG-111283
Change-Id: I265f611415a946468b828b9d41f549acfcc76233
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-11-24 18:34:03 +01:00
Ulf Hermann 1a8911a13d QmlCompiler: Don't generate invalid code for argument conversion
We need an additional pair of parentheses here.

Pick-to: 6.6 6.5 6.2
Fixes: QTBUG-119165
Change-Id: I0d8e810ebb5baad35e2cc1bc5c6581d1ba180dc8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-11-23 18:58:37 +01:00
Ulf Hermann 73f66c8f94 QmlCompiler: Do not generate lookups for bare meta enums
Such code is necessarily dead or uncompilable.

Pick-to: 6.6 6.5 6.2
Fixes: QTBUG-119090
Change-Id: I7319f7ceeb0b4994d5e974bbe8a9c3ba3bf72fc5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-11-18 08:36:01 +01:00
Ulf Hermann 096f3c3097 QmlCompiler: Don't access unavailable input accumulator on 'as'
We only read it if the target type is composite. Therefore, check for
composite first, before looking for the accumulator.

Pick-to: 6.6 6.5 6.2
Fixes: QTBUG-119122
Change-Id: I2a50214f76ee4ffe2f877dc690704e7475b8bd77
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-11-17 15:28:57 +01:00
Ulf Hermann 7df34d498d QmlCompiler: Retrieve original types for comparison
If an original type is merely wrapped into a more generic type by the
basic blocks pass, we know the original data is still there and can be
used for comparison.

Fixes: QTBUG-117795
Change-Id: Ia7582cd8ed48e47a3a1b3bd8e2595e9cb42828de
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-11-13 10:13:18 +01:00
Ulf Hermann ae39055313 QmlCompiler: Allow comparison of optional types
The only extra case we have to consider is the construction of an
optional type from a QObject-derived since that is stored in a QVariant
rather than a QObject*. Everything else we can compare is already
covered by the generic QJSPrimitiveValue comparison since
QJSPrimitiveValue can store undefined.

Fixes: QTBUG-117799
Change-Id: Iac89f28497c34d217af156d363b8beeda76174ef
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2023-11-09 19:12:37 +01:00
Ulf Hermann 674dc3f73d QmlCompiler: Always record original types for equality comparison
The shadow check may adjust the types later on and cause a different
comparison to happen than what we've expected when propagating. We can
only see this at code generation time.

Pick-to: 6.6 6.5 6.2
Task-number: QTBUG-117795
Change-Id: I04f1dd9902385f87114e48b0994e0f243f0c2c84
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2023-11-09 19:12:37 +01:00
Ulf Hermann d0484963f4 QmlCompiler: Allow internal conversions from wrapped original types
If an original type is merely wrapped into a more generic type by the
basic blocks pass, we know the original data is still there and can be
used for conversion.

This happens if we assign the same value once via a shadowable lookup
and once via an exactly typed one. The basic blocks pass then has to
produce a QVariant for the shadowable lookup. However, we know that it
can only contain the original type.

Fixes: QTBUG-117800
Change-Id: I42335c3404dbcf8c1e7ad6427d22643ad490a345
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-11-04 01:29:26 +01:00
Ulf Hermann cebb3a7320 QmlCompiler: Optimize trivial as-casts out
If you as-cast to a base type, we don't have to do any actual check.
Furthermore, retain the content variant through as-casts and print a
nicer error message if we cannot generate efficient code for an internal
conversion.

Task-number: QTBUG-117800
Change-Id: Iedaf4ca411be429eec6c9f23b9bd7f20794592ce
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-11-04 01:29:18 +01:00
Ulf Hermann 048c8f226a 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.6 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>
2023-11-04 01:29:09 +01:00
Ulf Hermann c662ae7cbf QmlCompiler: Generate jump code also when skipping an instruction
The next instruction may still need the type conversions even if we
don't need to generate any code for the current instruction.

Also, generate trace info for generate_DeadTemporalZoneCheck so that we
can recognize it in the generated code.

Amends commit 2c410317b6.

Pick-to: 6.6 6.5
Fixes: QTBUG-118514
Change-Id: I70ad3691486176de2177e9d5f538f7c99d121bfa
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2023-10-31 12:54:10 +02:00
Dmitrii Akshintsev c1320e7a35 Throw an exception in loadScopeObjectPropertyLookup when qmlScopeObject is null
When object is being destroyed, qmlScopeObject pointer is becoming null (I assume as part of the lookup invalidation?), causing nullptr dereferencing in the subsequent Init lookup stage.
This commit prevents it by introducing an "early exit" on the load stage.

Fixes: QTBUG-117866
Change-Id: Ifef1a0dd48a952f00f2c0d4d5015ec2f40b7f62a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2023-10-24 18:44:55 +02:00
Ulf Hermann 22eaa614ea QmlCompiler: Reject calls to one of multiple fuzzy overloads
If we cannot statically determine the right overload better don't call
any of them for now. Also, allow attempts to pass arguments as derived
types during type propagation.

The test shows that we don't properly pass the thisObject when calling
with metatypes. Fix that, too.

Pick-to: 6.6 6.5 6.2
Fixes: QTBUG-117922
Change-Id: I02e70ffb9a05f3cfedccafde6e16170b0efbcd29
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-10-23 14:44:19 +02:00
Ulf Hermann 1ba14d58eb QmlCompiler: Disallow reading enums from instances
Pick-to: 6.6 6.5 6.2
Fixes: QTBUG-118089
Change-Id: Ib98bb84159847439614341a3cbd4d34d6eabfc8a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2023-10-23 14:23:38 +02:00
Olivier De Cannière d4bab56356 codegenerator: Convert to the original type of registers for unary ops
When generating the code for unary operations, we converted from the
received type to the expected type in readAccumulator. Except, if the
latter was replaced by a different type such as with a generalization to
QVariant for example, then we would not retrieve the original type the
operations should be performed on but keep the replacement type.

Convert the received type to the original type instead of to the
replacement.

Fixes: QTBUG-117789
Pick-to: 6.6
Change-Id: Ia0109918443b1e1be2bc57b9d46a3a628799806b
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2023-10-06 18:06:47 +02:00
Ulf Hermann fa2b22a7a1 Add proper license header to tst_qmlcppcodegen.cpp
Fixes: QTBUG-105839
Change-Id: Icbb4c6e462c08be019ca203b11aaff840297ccd6
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-09-29 18:04:22 +02:00
Ulf Hermann a173d50a9e QmlCompiler: Implement GetIterator and IteratorNext
Each GetIterator generates

* A unique iterator variable that keeps track of the current index
* In the case of for...of a copy of reference to the list being iterated

The result register holds a pointer to the unique iterator so that it
can be loaded and stored without resetting it.

In order to do anything meaningful with iterators (in the tests) we also
need to allow LoadElement with our "optional" types. That is a
conversion of undefined and some other type to QVariant or
QJSPrimitiveValue. This follows the same pattern as the other
"optional"s we already have.

For...of is currently not testable because it requires exception
handlers. The tests will be added once we get exception handlers.

Task-number: QTBUG-116725
Change-Id: I167fe16b983dc34bf86e1840dfcbf2bf682eecc1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-09-21 10:11:05 +02:00
Ulf Hermann 3ca5a7b3b6 QmlCompiler: Clean up equality operators
The special cases added for the number and null operations are generally
useful also for other kinds of equalities and vice versa. Furthermore,
there is no point in std::move'ing registers into equality operators.

Task-number: QTBUG-115110
Change-Id: I6de634ee45e13aefd069677c4bf75020875e09fa
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-25 23:58:12 +02:00
Ulf Hermann f839171eef QmlCompiler: Allow creation of actual QVariantMaps from object literals
There are places where we need this:

a, If the method in question actually takes a QVariantMap as argument.
b, If the resulting value can be shadowed. In that case we expect a
   QVariant. The engine has to internally convert to the expected type
   then.

Change-Id: Ic5b3faab4578d64ca757de644fe69660fd70e52a
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>
2023-08-25 20:36:46 +02:00
Ulf Hermann 555125416e QmlCompiler: Allow coercing date values to numbers
This is the equivalent of JavaScript's valueOf().

Change-Id: If850519d6dbc7354b447acb6aad8ac04211d059d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
2023-08-25 20:36:37 +02:00
Ulf Hermann ede3389a3e QmlCompiler: Allow setting values in sequences
Since we have write-back available now, this is not difficult anymore.
This does not yet cover setting properties of value type objects stored
in sequences such as "a[i].b = c". You can only set the whole element.

Task-number: QTBUG-116011
Change-Id: Id5f7a19125897602880e573d5f25b025f9b91f34
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
2023-08-25 20:36:33 +02:00
Ulf Hermann 72e9f47526 QmlCompiler: Allow write-back to members of objects
This covers recursive write-back, but not write-back to members of
singletons or attached types, write-back of lists.

Task-number: QTBUG-116011
Change-Id: I6d33fae3bf9fdaed8d696a708124e0a707ecb07e
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-24 12:39:43 +02:00
Ulf Hermann 8d9dfd3347 QmlCompiler: Fix conversion from/to void
We can convert everything to void, but we can only convert from void if
the result is either void or the invalid type.

Pick-to: 6.6
Fixes: QTBUG-116088
Change-Id: I532055405865c5b1581f79cc5d76c253bce6138d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2023-08-23 15:30:11 +02:00
Ulf Hermann 2eac7350c0 QmlCompiler: Stabilize test
Loading the implicit import might add extra types that use up indices.
So, make sure the implicit import has already been loaded at that point.

Use a file that only has one type reference so that the ordering of type
references cannot mess up the selection of indices for types.

Change-Id: Ia33979e660e114ef608e1f5e22252c822c7f3d61
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2023-08-22 20:11:34 +02:00
Ulf Hermann d908d5e57c QmlCompiler: Allow construction of Array objects
Currently, only the constructor form of the Array function is compiled.
We only compile construction of Array objects if we can determine that
they are immediately assigned to a typed list. Consequently, we don't
have to deal with sparse arrays.

Change-Id: I2abd15139eb9a0d530ad49df7313b8dba415ae77
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-22 17:16:53 +02:00
Ulf Hermann 0f23346d2a QmlCompiler: Allow construction of Date objects
We map Date to QDateTime and special-case its constructors.

Task-number: QTBUG-111624
Change-Id: I0496f853613da3ccee9b6f6c4cf0adffa064f9f8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2023-08-18 14:26:04 +02:00
Ulf Hermann f6735dba95 QmlCompiler: Fix console logging
Store a copy of the UTF-8 data for file and function so that we don't
run into heap-use-after-free.

Set the instruction pointer before calling the log function so that we
get a correct line number.

Pick-to: 6.6 6.5
Fixes: QTBUG-114655
Change-Id: I38249fe52719ddad620033716ff22b2087ab8382
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-15 17:48:43 +02:00
Ulf Hermann 759b8383d7 tst_qmlcppcodegen.cpp: Restore ordering of functions
We want them alphabetically sorted so that we minimize merge conflicts.

Change-Id: If6509fb1d196a10898fd6d9a5f51a9da678ad3c9
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-15 14:13:32 +02:00
Ulf Hermann d07744ef5d QmlCompiler: Fix SetLookup on shadowable properties
If we are procedurally setting a shadowable property, the read register
for the value will be converted to var. We can therefore not just
retrieve the property type again in the code generator to determine what
we have to do.

What we actually need is the information on the original scope type of
the lookup. We need to know what exactly the base type was supposed to
be. To that effect, store the scope of the target for each conversion in
QQmlJSRegisterContent.

We need to circumvent the questionable optimization of "deduplicating"
functions that certain compilers exhibit, like we do for the getters.

Pick-to: 6.6
Fixes: QTBUG-115526
Change-Id: I361f2e46e39ece7892df72ae13ec756f9aec4adf
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-08 15:12:46 +02:00
Olivier De Cannière 2cf9aeccdd Compiler: Separate function prolog block and add validation of blocks
The function prolog logic is now separated in its own basic block. The
first "real" block with user code starts at offset 0.

Having the function prolog as a hidden part of the first block caused
some inconsistencies in block generation and would create empty blocks.
This happened for example when a back edge of a loop would target offset
0 in code where a loop condition is the very first set of instructions
that are run. This is because the target block offset didn't exist due
to it being part of the hidden prolog block.

Validation for the basic blocks was also added. This checks for three
things at the moment:
1. That return and throw blocks don't have jump targets.
2. That the basic blocks graph is connected.
3. That jump targets are the first offset of a block.

Test tst_QmlCppCodegen::basicBlocksWithBackJump_infinite() is expected
to fail because it contains an infinite loop and the basic blocks that
are generated for it are inconsistent due to dead-code elimination
happening earlier in compilation.

Debug outputs for dumping basic blocks were also adapted to reflect
these changes.

Change-Id: I513f73856412d488d443c2b47a052b0023d45496
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-04 09:34:09 +02:00
Ulf Hermann fa6aedf7ac QmlCompiler: Allow calling methods on potentially undefined QObjects
We can use the same technique as for GetLookup there. Just check the
variant for validity to see if we can call it.

Change-Id: I1bcf4a5a84f47e0236762827488bc5d03e015efb
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-07-28 16:42:45 +02:00
Fabian Kosmale e9c87ad1b2 tst_qmlcppcodegen: Split enum test
That makes it more clear which ignoreMessage belongs to which part.

Change-Id: I4c2bcc16b80204c6bb55c18459b7e8b0b1b298be
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2023-07-27 09:36:50 +02:00
Ulf Hermann 81bab13560 QmlCompiler: Force QObject* for LoadElement on list properties
In the presence of incomplete type information we may otherwise conclude
that the value type is QJSValue and generate broken code.

Pick-to: 6.6 6.5 6.2
Change-Id: I533f704a422d0efe8b7b5bb0a170966e9f290b1f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-07-26 16:54:52 +00:00
Ulf Hermann 747c860354 QmlCompiler: Correctly handle lookups in results of method calls
Method calls often return just QVariant because we cannot be sure that
the method hasn't been shadowed. In order to figure out the right lookup
we should look at the type the type propagator assumed as the base of
the lookup. If the type propagator was assuming a list-length lookup we
need to try and generate a list-length lookup. If the base turns out to
be a QVariant after shadow-checking, the code generation will cleanly
fail (and refrain from generating bad code).

Amends commit 46cc70e2aa.

Pick-to: 6.6
Fixes: QTBUG-115278
Change-Id: I24dcd06161eb1af44450fb663d68a16d89efd6ac
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-07-25 16:33:29 +02:00