| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We assume that QML or JS code comes from a trusted source. Therefore,
most files are deemed to be significant even if they parse data. This
includes the source code itself but also the associated metadata or
cache files.
However, the QML compiler also generates C++ code. Extra care needs to
be taken with the generator as a vulnerability there could propagate and
have a disproportionate effect on the program's security. It is marked
as critical.
QUIP: 23
Fixes: QTBUG-136195
Pick-to: 6.10 6.9 6.8
Change-Id: I70630361ec8e9cb3969f78a3fdf36a41334a33b3
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
The typeName may be incorrect if the property's type is later adjusted.
Task-number: QTBUG-134790
Pick-to: 6.9 6.8
Change-Id: I58c95e873a1d1eb0a2c9d0d0c7b34664d75eadff
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
The code generator uses temporary register contents for various
purposes. None of those survive across instructions since there wouldn't
be anywhere to store them. We don't need to keep those temporaries
around until the end of the compilation. Trim them after each
instruction.
Task-number: QTBUG-124670
Change-Id: Ia6ff7ff2a9c7a5e99ab37ab2cc3e5f7ee756b57c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
There is no need anymore to create a new QQmlJSRegisterContentPrivate
just to add a storage type. Furthermore, we should record the
generalization origin when generalizing storage.
Task-number: QTBUG-124670
Change-Id: Ib1413e645fbc927806f85c7aa235c95a4cbfaa96
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
| |
It's only a single pointer these days.
Task-number: QTBUG-124670
Change-Id: Id51fe268108733b07d77c70531f38914a8adfdae
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
| |
The name should say what kind of QQmlJSRegisterContent it creates.
Change-Id: Ia77bfc7c2a34395ca9e54ba496acd9d6883152cb
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
| |
Rename some methods and write some comments.
Task-number: QTBUG-124670
Change-Id: I3046d545374c92dd7441d58d2b8fe2abc25078b8
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is the central piece of the refactoring. Instead of re-writing the
QQmlJSScopes on adjustment we now rewrite the QQmlJSRegisterContents.
The main benefit of this is that we can locally link
QQmlJSRegisterContents together without invoking QQmlJSTypeResolver. The
other benefit is that we gain more control over where the re-written
types show up. QQmlJSScope is stored in many places that should really
not be re-written. QQmlJSRegisterContent is only used locally when
analyzing a binding or function. Finally, we can now chain the type
adjustments with other operations on QQmlJSRegisterContents, without
restrictions.
This makes a few methods of QQmlJSTypeResolver obsolete. Those will be
removed in a separate step.
In order to get this right, we need to deviate from the notion that
every read register is either a rename or a conversion. Rather, we must
pass any "as-is" read of a register through that way. We rely on those
to be re-written when the original register is.
Task-number: QTBUG-124670
Change-Id: I0d968dfe495b82d9d9f67d598447bd2ad5bdcd04
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a major departure from the previous architecture. We can now
alter a QQmlJSRegisterContentPrivate after it has been created. This is
fundamentally necessary so that we can add further links to other types
as they are discovered. With an immutable QQmlJSRegisterContentPrivate
we have to clone every time which makes for long and rather meaningless
chains of links that are hard to navigate, eventually. Making the
register content non-const will in turn allow us to uphold the
immutability of QQmlJSScope. That is much more important because it can
fundamentally be used across different compilations.
Task-number: QTBUG-124670
Change-Id: Iacee705be3260da0a2bc91c6758f91c70a137065
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
| |
The other transformations that previously used castTo() are better
phrased as conversions rather than casts.
Task-number: QTBUG-124670
Change-Id: I3cf885edcac6fa665a6ad12b97f6d063709a1632
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
| |
We will need to link the storage to its adjustment eventually.
Task-number: QTBUG-124670
Change-Id: I50db4f7af34cc2f41f9a43e5fe271ecdf75fe655
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We want an easy way to hold pointers to other QQmlJSRegisterContents in
QQmlJSRegisterContent. Furthermore, copying a QQmlJSRegisterContent so
far is very expensive. Solve both problems by introducing the PIMPL
pattern with a shared d-pointer.
This also changes the equality semantics of QQmlJSRegisterContent. Two
QQmlJSRegisterContents are only equal if they contain the same d-pointer
now, not if their contents are otherwise equal. However, since we
generally don't rely on immediate equality of QQmlJSRegisterContent
anyway, this is not a problem. QQmlJSTypeResolver::equals() still works.
There is one place where the equality was used, though. That one is
adapted.
Furthermore, we now want to keep the register contents in a pool that's
automatically cleared when we're done with our analysis. Therefore the
creation methods cannot be static anymore and storedIn() as well as
castTo() need to go through the pool as well.
Task-number: QTBUG-124670
Change-Id: I0a51b609fc769ccb33c1d82930bda83c2a40e1a5
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
| |
We can use it for JavaScript local and global scopes, too. To this end,
check for the actual QML scope object where we want that one.
Task-number: QTBUG-124670
Change-Id: I908a4f122a83d6685129cb24959353a1169faae0
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
We can infer from the method itself whether it's a JavaScript call or a
C++ call. Therefore, what we need to carry around is the
QQmlJSMetaMethod. This way we can do with only one content variant for
all kinds of calls.
Task-number: QTBUG-124670
Change-Id: I1d8193018f0224924b8aef5181c398674bde857d
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
Instead of having a cross product of "scope" and "object" on the one
hand and "property", "method" and "enum" on the other hand, use the
scopeType to resolve what kind of element a property, method or enum
belongs to.
Task-number: QTBUG-124670
Change-Id: Ia9db05e13979e55e0ed7912afc2003dfd018987a
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
With this in place, we don't have to synthesize conversion origins
anymore and get to trace values through conversions.
Task-number: QTBUG-124670
Change-Id: Ib3646d410526eca7b982f86adef9d5a387ff56ea
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is the first step in chaining up the values in a graph. We can only
derive the next node of the graph if we have a full previous node.
QQmlJSRegisterContent will ultimately just be a container for a node.
Prepare for this by requiring QQmlJSRegisterContent as input when
creating a new register content.
In some cases we can't actually nest contents, yet. Therefore we chicken
out by creating synthetic QQmlJSRegisterContents.
Task-number: QTBUG-124670
Change-Id: Idad793692ca78d71ba17107d396e508bc1392b67
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
|
| |
|
|
|
|
|
|
|
| |
The syntax is slightly annoying, but we want the generic names like
Property and Method for the public ContentVariant enum.
Change-Id: Ifb70340bb5143854a88ff3de78bcb585f49872f1
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
| |
There is no point in reporting the C++ name of the type, but then not
going all the way and reporting the type we actually mean.
Change-Id: I9d12d34ab65766f7a396c70ddae2bbe573fa7778
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
|
| |
|
|
|
|
|
|
|
| |
We don't need the type resolver for that. And since we always want the
"fancy" name, drop the extra argument.
Change-Id: I14278b5a297fc0e8101f03e5098a831a91deaf9e
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
| |
Add a separate pass to populate the stored types and only run that after
we're done with all the type propagation and optimization.
Task-number: QTBUG-124670
Change-Id: I740063908b22684f5d2c72d6261fad98850d8636
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
We don't actually need the stored type until we hit the storage
generalizer. There are two cases where the stored type is the same as
the contained type: methods and import namespaces. Store the contained
type separately in those cases.
Task-number: QTBUG-124670
Change-Id: I395203ab204162b2754914438f56546e07453272
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
| |
Fixes: QTBUG-124220
Pick-to: 6.7
Change-Id: Ic31b90b0408d855a45e17647ab659fbbc6e17633
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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>
|
| |
|
|
|
|
|
|
|
| |
This way we can generate a separate register variable for the result of
each lookup, which guarantees that we can write back to it if necessary.
Task-number: QTBUG-116011
Change-Id: I1d2b8948d8edb66f0665399768df194065dc99be
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since lists are allowed as property types, you should be able to pass
them as arguments to methods, too. For now we only handle QML-defined
methods, implemented by adding JavaScript functions to your QML
elements. The usual type coercion rules apply if you pass JavaScript
arrays to such methods. That is, it usually works.
We now resolve properties with the "list" flag to their actual types
(QQmlListProperty or QList) already when populating the QQmlJSScope, and
store the list types as members of QQmlJSScope rather than as a special
map in QQmlJSTypeResolver. This allows us to do the same to lists passed
as arguments and simplifies some of the type analysis.
Fixes: QTBUG-107171
Change-Id: Idf71ccdc1d59f472c17084a36b5d7879c4d959c0
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a semantic patch using ClangTidyTransformator to convert
sequences of Q_UNREACHABLE() + return into Q_UNREACHABLE_RETURN(),
newly added to qtbase.
const std::string unr = "unr", val = "val", ret = "ret";
auto makeUnreachableReturn = cat("Q_UNREACHABLE_RETURN(",
ifBound(val, cat(node(val)), cat("")),
")");
auto ignoringSwitchCases = [](auto stmt) {
return anyOf(stmt, switchCase(subStmt(stmt)));
};
makeRule(stmt(ignoringSwitchCases(stmt(isExpandedFromMacro("Q_UNREACHABLE")).bind(unr)),
nextStmt(returnStmt(optionally(hasReturnValue(expr().bind(val)))).bind(ret))),
{changeTo(node(unr), cat(makeUnreachableReturn,
";")), // TODO: why is the ; lost w/o this?
changeTo(node(ret), cat(""))},
cat("use ", makeUnreachableReturn));
a.k.a qt-use-unreachable-return.
subStmt() and nextStmt() are non-standard matchers.
There was one false positive, suppressed it with NOLINTNEXTLINE.
It's not really a false positiive, it's just that Clang sees the world
in one way and if conditonal compilation (#if) differs for other
compilers, Clang doesn't know better. This is an artifact of matching
two consecutive statements.
Change-Id: I3855b2dc8523db1ea860f72ad9818738162495c6
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.
Pick-to: 6.4
Task-number: QTBUG-67283
Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
|
| |
|
|
|
|
| |
Task-number: QTBUG-101408
Change-Id: Ic925751b73f52d8fa5add5cacc52d6dd6ea2dc27
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
| |
Apparently we do that somewhere. It should not just crash.
Pick-to: 6.2 6.3
Task-number: QTBUG-102147
Change-Id: Id612e0543d8794aa4f334a899b117142b7a8cd38
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
| |
We need to export all the classes used by qmlsc, and we need to use the
private export macro for private symbols.
Change-Id: I91d59611e864621dc2c49b9383596e706529bd42
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
Previously the filename was only available for C++ types that have been
exposed via qmltypes. Now every scope has a valid filename to reference.
This is important in order to give more useful hints to the user and
will also prove useful for debugging.
Change-Id: I6142b58278f388814514fffd86cbc241eb969bb2
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Introduce a new kind to QQmlJSRegisterContent: "conversion". This is
what we store when we merge multiple types together, or convert a
selection of types into a new one. This way we can record what the
original types were, and later figure out whether we can losslessly
convert them already at the point where we store them.
For now, only merges are implemented.
Change-Id: If4ad0b1f075199e6aa1532959cf9591ba6755709
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
| |
|
|
|
|
|
|
|
|
|
| |
The code generator needs to see the modulePrefix as a separate step in
order to generate sensible code. The savedPrefix we had before was not
exposed to the code generator. As an added benefit we can also check
that we don't refer to singletons as properties of objects this way.
Task-number: QTBUG-95822
Change-Id: Ia8992dba340bf0552e7647f0d66b441f1ac1b8c8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|
|
|
Move the type inference code so qmllint can benefit from the improved type analysis.
Change-Id: I00b2fad8334ec19fb33a45b3ceec9d6c49d12e93
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
|