| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
| |
Task-number: QTBUG-133349
Change-Id: Iafb2da52ea6230ead945f0eda978c53ca6a8e7c6
Reviewed-by: Sami Shalayel <[email protected]>
|
|
|
|
|
|
|
|
|
| |
The compiler can't optimize it away, and it's rather expensive to
create and destroy a QSharedPointer on every usage of operator->.
Task-number: QTBUG-133349
Change-Id: If1199a18b904ebce9921cc7b863792f407e45e0d
Reviewed-by: Olivier De Cannière <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Do not populate a pointer eagerly if it was already populated when its
factory got reset. Instead reset the underlying shared pointer to
delete the stale data. Amends 13761ee3c7d6ecb756db490d8c1fa8980117dca4
that wanted to avoid having stale data around.
Add a test that reproduces the stack overflow when the pointer get
eagerly populated, and make sure the stack size is big enough even for
asan builds.
Fixes: QTBUG-132134
Pick-to: 6.8 6.9
Change-Id: I8e2a5ce7fc99b1ec33d31535dc6b2675ab623349
Reviewed-by: Ulf Hermann <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It seems that the current lazy QmlFile implementation does not take into
account the commitToBase workflow used in qmlls, which leads to crashes
and weird behaviors.
Change the logic in QDeferredFactory<QQmlJSScope> to allow a custom
TypeReader: QQmlJSTypeReader always reads from disk which is bad
because qmlls operates most of the time on in-memory files and
introduces an unnecessary IO operation, and therefore a new TypeReader
is introduced in this commit for files loaded in the Dom.
Populate lazy QmlFiles into the environment that they were loaded into
with the new TypeReader before commitToBase() calls, and into the base
environment after the commitToBase() call. This fixes the crashes during
completion where a heap-use-after-free happened when a lazy file tried
to populate itself after a commitToBase call using a destructed
temporary DomEnvironment.
Add a resetFactory() method to QDeferredSharedPtr to force
recompute a QQmlJSScope when a file was changed without having to
recreate all the qqmljsscopes for the other files, and use it also
during commitToBase() calls to update the environment needed for the
lazy loading. If the previous factory was used already, then
the qqmljsscope is eagerly populated to avoid stale data.
Also make sure to update the loadPaths for the build directory tests
when getting a SemanticAnalysis struct from the base environment.
Recreate the "completion crash" scenario from QTBUG-124799 in
tst_qmldomitem. Add tests to make sure that files are correctly
populated before and after commitToBase() calls.
Also add a test in tst_qmlls_qqmlcodemodel to make sure that files are
correctly lazy loaded in qqmlcodemodel, and simplify
qqmlcompletionsupport's completions method by early exiting.
Make populateFromQmlFile populate the logger in the same way as the
QQmlJSTypeReader does.
Fixes: QTBUG-124799
Fixes: QTBUG-125388
Change-Id: Id8bd7a1cbe60ba961eadb37b121f8f0670b863f4
Reviewed-by: Fabian Kosmale <[email protected]>
Reviewed-by: Ulf Hermann <[email protected]>
|
|
|
|
|
|
| |
Task-number: QTBUG-117983
Change-Id: I893ba2a6c83af92d65d843b6a37bb14c6c1e45bf
Reviewed-by: Ulf Hermann <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
QDeferredSharedPointer and its weak companion are shared pointers,
whose ctors QUIP-0019 asks to mark as [[nodiscard]].
QUIP: QUIP-0019
Task-number: QTBUG-104168
Pick-to: 6.6
Change-Id: Iba523f92276f4c77db21f8775629ae2c1b0dd43f
Reviewed-by: Ulf Hermann <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Mark operations [[nodiscard]] which (directly or indirectly) execute
lazyLoad(). Rationale: we should warn if deferred initialization is
triggered without using the result. Intended uses can still use
casting to void (and hopefully a comment) or [[maybe_unused]] to
indicate the code works as intended.
QUIP: QUIP-0019
Task-number: QTBUG-104168
Pick-to: 6.6 6.5
Change-Id: Iece9b36079c4af8d790b19703f81b284d507bf46
Reviewed-by: Ulf Hermann <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 <[email protected]>
Reviewed-by: Ulf Hermann <[email protected]>
Reviewed-by: Marc Mutz <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The factory should populate the pre-existing scope rather than copy it
into place. This way we can detect inheritance cycles involving the
pre-existing scope.
However, now we may detect the inheritance cycles earlier, when
resolving the types inside the lazy loading. We have the right pointers
available there now, after all. Therefore, add a way to propagate base
type errors out of the factory. When clearing the base type, we can now
give a reason for that. When checking the inheritance cycles we
retrieve that reason and log it.
We also remove the special casing of the ScopeType property of
QQmlJSScope. There is no real reason to set it in the ctor. As we
delay the population of QQmlJSScope now, we have to set it later.
Pick-to: 6.2 6.3
Task-number: QTBUG-102153
Change-Id: I49cf6e20f59fbdb6ed98a82040b3b159676f5975
Reviewed-by: Andrei Golubev <[email protected]>
Reviewed-by: Qt CI Bot <[email protected]>
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
| |
Change-Id: I71a53492d046232109108f521e9223584b798e3c
Reviewed-by: Maximilian Goldstein <[email protected]>
|
|
|
|
|
|
|
| |
We don't need to load the types just to compare the pointers.
Change-Id: If93f7460f6e247f119f366a4c02a98d3e5f6535f
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
|
| |
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 <[email protected]>
|
|
|
|
|
|
|
|
|
| |
Converts qmlcompiler into a shared library so it isn't duplicated when
statically linked in tools and so that plugins can link against it.
Change-Id: I91e13cc588796f71a5463dbdce21e42a74120565
Reviewed-by: Fabian Kosmale <[email protected]>
Reviewed-by: Qt CI Bot <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
See script in qtbase/util/includeprivate for the rules.
Since these files are being touched anyway, I also ran the
updatecopyright.pl script too.
Change-Id: Ib056b47dde3341ef9a52ffff13ef677e471674b6
Reviewed-by: Mitch Curtis <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
As we create the actual QSharedPointer and construction time, we can
compare for equality or null without lazy loading. Furthermore, the
factory, being a template parameter, can provide interesting additional
functionality. Make it available in the public interface.
Change-Id: Id1d4dd48d87c259dc93ee50e3b2d2510cdb54526
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Comparing via operator== a QDeferredSharedPointer with a QSharedPointer
is ambiguous, as both convert to each other implictly, and there's only
operator==(QDSP, QDSP) and operator==(QSP, QSP) defined. Therefore a
"mixed" comparison is ambiguous: there's no dedicated operator==,
and one can convert either parameter to the "other type" to get a
viable candidate, and no conversion is better than the other.
The result is:
../src/qmlcompiler/qqmljstyperesolver.cpp: In function ‘bool isAssignedToDefaultProperty(const ConstPtr&, const ConstPtr&)’:
../src/qmlcompiler/qqmljstyperesolver.cpp:565:29: error: ambiguous overload for ‘operator==’ (operand types are ‘QSharedPointer<const QQmlJSScope>’ and ‘const ConstPtr’ {aka ‘const QDeferredSharedPointer<const QQmlJSScope>’})
565 | if (binding.value() == child)
| ~~~~~~~~~~~~~~~ ^~ ~~~~~
| | |
| | const ConstPtr {aka const QDeferredSharedPointer<const QQmlJSScope>}
| QSharedPointer<const QQmlJSScope>
Given that apparently implicit convertibility between QDSP and QSP
is wanted, add mixed comparison operators to remove the ambiguity.
Pick-to: 6.2
Change-Id: Ifcb1a2d86986d83c6f488097c9b4c8cb35db31d9
Reviewed-by: Qt CI Bot <[email protected]>
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
It calls QWeakPointer::data, which shouldn't actually exist and is not
actually used anywhere.
The safe way to access the data of a weak pointer is to create a shared
pointer from it, which ensures that there is a strong reference to the
data while we are accessing it.
Change-Id: I89ddfb85735d2ee56a8a882373ffc0444b564b13
Reviewed-by: Ulf Hermann <[email protected]>
|
|
|
|
|
|
|
|
| |
Weak pointers shouldn't be used as keys of a hash map, and in fact are
not used as such in declarative.
Change-Id: Ib84b9a090683332ae2c57e59506caae1aac62a48
Reviewed-by: Ulf Hermann <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
Otherwise a lazy loaded deferred pointer is different from an
immediately loaded deferred pointer of the same object.
Pick-to: 6.2
Change-Id: I235907f82f10d2af5002ae6c3a852f3235dd802c
Reviewed-by: Andrei Golubev <[email protected]>
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
| |
Because QSharedPointer (and almost any other smart pointer) provides it
Change-Id: I7e0cf0d700ed72de56b6949ee18b3469881088b3
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
If the content is not loaded, yet, the data is always null. If it is
loaded, the result might be null. So, in order to know, we have to load.
The same holds for deferred weak pointers, the hash functions, and the
equality operators.
Change-Id: I20eec58efe5da604187c34578ee40f769090c910
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
|
| |
It is expected to return an unsigned value.
Change-Id: Id75c0887de7e9b0eeab378041598621c89507501
Reviewed-by: Fabian Kosmale <[email protected]>
Reviewed-by: Maximilian Goldstein <[email protected]>
|
|
|
|
|
| |
Change-Id: I2191660b731d85495d0e90152e0fe493553b7a2f
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
|
|
|
|
|
| |
Only this way we avoid infinite recursion on cyclic references.
Change-Id: I4d6323a093d17f7d55965dc40f9dc5f1a647df9c
Reviewed-by: Fabian Kosmale <[email protected]>
|
|
When importing a directory we most likely don't need all of the files in
the directory. Therefore we now parse them only when they are accessed.
This speeds up the execution and will allow us to process imports
recursively without running into infinite recursion.
Change-Id: I0c79313de792249e6bb86144b5014a7787dbdc5b
Reviewed-by: Fabian Kosmale <[email protected]>
|