summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
Commit message (Collapse)AuthorAgeFilesLines
* Merge remote-tracking branch 'origin/tqtc/lts-6.2.8' into ↵Tarja Sundqvist2024-01-228-59/+130
|\ | | | | | | | | | | | | | | | | tqtc/lts-6.2-opensource Conflicts solved in a file: src/corelib/io/qstandardpaths_android.cpp Change-Id: Ie8cef36c1379679ca358df50c56b3c25aa15c5d6
| * QCryptographicHash: fix UB (data race on concurrent result()) [2nd try]Marc Mutz2023-03-111-36/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The previous attempt at fixing QTBUG-110058, ccad719d2e935306e601b0f6af5ff2acb7cd272e, was incomplete: - the if (result.isEmpty()) check at the beginning of finalize() was not protected, so it raced against the assignment at the end of finalize(), which was protected - because the mutex was not locked during the finalization of the hash algorithm, two threads could perform this operation simultaneously, which isn't such a bad idea in principle, as it can reduce latency, but for that to work, the losing thread needs to throw away its own work and adopt the work of the other thread, but that wasn't done: both threads would write their result to 'result', just one after the other, but that's still a data race, since the eventual _reader_ of the result cannot be protected (is outside the class). Besides, we don't even know whether the algorithm-specific finalization functions are ok with being called from separate threads on the same context object - in addition, the mutex wasn't necessary when finalize() was called from the static hash() function, as no sharing could possibly take place there (the state is function-local) Fix all of the above by largely reverting the first attempt, dragging the result.isEmpty() check out of finalize() and into resultView() and instead simply holding the mutex over these two calls in resultView(). To see why this is sufficient, consider that resultView() is now idempotent again: the result is written once, the next thread waits and then finds the work done. All following accesses to the result are then reads, which happen-after the write at the end of finalize(). The accesses to 'result' from reset() need no protection, as reset() is a mutable function, and calling a mutable function on a shared QCryptographicHash object is already UB. Only two const functions may be called that way. Manual conflict resolutions: - missing OpenSSLv3 code in 6.4 - different order of Private member fields - Private::method mutable - no ctor in Private - no Private::reset(), so kept everything in result() - no static hash() optimization, so no non-locked finalize() there - as a consequence, just wrapped the whole body of result() in a scoped_lock. Fixes: QTBUG-110058 Change-Id: Ia8ac095b785519682090801c1012e9dded6d60b2 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit b904de43a5acfc4067fc9e4146babd45c6ac1138) Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
| * QVarLengthArray: fix UBs in insert(it, n, v) ([basic.life], invariants)Marc Mutz2023-03-091-22/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the same vein as e24df8bc726d12e80f3f1d14834f9305586fcc98 for emplace(it, v) and insert(it, rv), this patch addresses the identical issues in insert(it, n, v). The solution is unsurprisingly the same: q_rotate() after a resize(size() + n, v). The 6.2- code will need to look different, because resize(n, v) didn't exist there. Manual conflict resolutions: - ↑ that - no resize_impl() in this branch, so wrote one as a private method Change-Id: I1ce91969abc20f2a1e5d05a8545b009a2e0994f6 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> (cherry picked from commit fed5f2445480f7cf045e93761dc902f771cbf3da) Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
| * QVarLengthArray: Extract Method QtPrivate::q_rotate()Marc Mutz2023-02-272-6/+21
| | | | | | | | | | | | | | | | | | It seems like we'll need this in lots of other places, too. Change-Id: I767495c2eb02a2fc85b6f835ad9003fa89315c7f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> (cherry picked from commit 147dd6e82f41778060bdadf9b2a792bd11e1bc1e)
| * QVarLengthArray: fix UBs in emplace()/insert() ([basic.life], broken class ↵Marc Mutz2023-02-211-21/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | invariant) There are two problems in emplace_impl() (the same code exists as rvalue insert() since 5.10): First, the old code updated size() at the end of the function. However, if, after constructing the new end element, one of the subsequent move-assignments fail (throws), then the class invariant that size() be the number of alive elements in the container is broken, with the immediate consequence that the QVLA dtor would not destroy this element, but surely other unpleasantness (UB) that the C++ lifetime rules decide to throw our way. Similarly, in the trivially-relocatable case, the memmove() starts the life-time of the new end object, so if the following placement new fails, we're in the same situation. The latter case is worse, though, since here we leave *b in some weird zombie state: the memmove() effectively ended its lifetime in the sense that one mustn't call the destructor on the source object after trivial relocation, but C++ doesn't agree and QVLA's dtor will happily call b->~T() as part of its cleanup. The other ugly thing is that we're using placement new into an object that C++ says is still alive. QString is trivially relocatable, but not trivially copyable, so we can't end a QString's lifetime by placement-new'ing a new QString instance into it without first having ended the old object's lifetime. The fix for both of these is, fortunately, the same: It's a rotate!™ By using emplace_back() + std::rotate(), we always place the new object in a spot that didn't contain an alive object (in the C++ sense) before, we always update the size() right after doing so, maintaining that invariant, and we then rotate() it into place, which doesn't leave zombie objects around. std::rotate() is such a fundamental algorithm that we should trust the STL implementors to have optimized it well: https://stackoverflow.com/questions/21160875/why-is-stdrotate-so-fast We know we can do better only for trivially-relocatable, but non-trivially-copyable types (ex: QString), so in order to not lose the memmove() optimization, we now fall back to std::rotate on raw memory for that case. Amends dd58ddd5d97f0663d5fafb7e81bff4fc7db13ba7. Manual conflict resolutions: - no q20::construct_at() in 6.2 - no QVLAStorage/Base/QVarLengthArray split in 6.2 - no emplace_back() in 6.2 (use append(rv) instead) - no emplace() in 6.2 (the same code here implements insert(rv)) Change-Id: Iacce4488ca649502861e0ed4e084c9fad38cab47 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit e24df8bc726d12e80f3f1d14834f9305586fcc98) Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
| * QVarLengthArray: clear() is not resize(0)Marc Mutz2023-02-151-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The latter needs the value_type to be default-constructible, which shouldn't be required to clear() a container. Use std::destroy_n() instead. [ChangeLog][QtCore][QVarLengthArray] clear() no longer requires the value_type to be default-constructible. Manual conflict resolutions: - No QVLAStorage/Base/QVarLengthArray split in 6.2, yet Change-Id: I806de8f3826b50c0bd38156892c3afeb15f13ac9 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit fbfee2d7c59a7c6cd17ae7a3f63f983b9f3316f5) Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
| * QCryptographicHash: add a mutex to writing to the resultsThiago Macieira2023-02-021-30/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QCryptographicHash::result() and resultView() are const, therefore two threads can call them on the same object. Given that the finalization of the hash is not a trivial operation but doesn't modify the state, let's do it without a locked mutex, onto a temporary stack buffer. Then we lock the mutex to copy said result to our cached value. Fixes: QTBUG-110058 Change-Id: Ide4dbd0777a44ed0870efffd17394bf72785eabb Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> (cherry picked from commit ccad719d2e935306e601b0f6af5ff2acb7cd272e) Reviewed-by: Marc Mutz <marc.mutz@qt.io>
| * Move QTypeInfo<std::pair> from qpair.h to qtypeinfo.h to avoid ODR violationMarc Mutz2023-01-141-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | First off, this doesn't cost us anything, because std::pair is defined in <utility>, which qglobal.h unconditionally includes in C++ TUs. More importantly, it prevents ODR violations: when a TU includes only qtypeinfo.h, it will find std::pair<int, int> to be of Q_COMPLEX_TYPE, in constrast with a TU which includes qpair.h, which will find it to be of Q_PRIMITIVE_TYPE instead. [ChangeLog][QtCore][QTypeInfo] The QTypeInfo for std::pair/QPair will now be correct even if qpair.h hasn't been included, fixing an One-Definition-Rule (ODR) violation. Change-Id: I51f579c123183af25aac9f0ffcf077f752848fb1 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit f6b026eed1a4a3441ba9b1b92a9eaf2c17d69253) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
| * [doc] QSharedPointer: add some missing docsMarc Mutz2022-12-222-0/+57
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Added docs for - move-ctor, -assignment operator - move-construction and -assignment from QSP<X> - qHash() There's more stuff missing, but I declare 'twas enough qdoc wrangling for this round. The texts are taken from other smart pointer docs, esp. QESDP, so they're consistent. Fixes: QTBUG-83134 Fixes: QTBUG-63700 Change-Id: Iff980d043e1635ed6cfdd3113c68bc23f3a0bad7 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 5dc0f52e7047ca5927e6741fda554cb090184b71) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
| * QtMiscUtils: add missing toAsciiUpper(), use it in mocMarc Mutz2022-12-201-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ... to make moc code locale-independent. The C toupper function is locale-dependent. Given the right locale (Türkiye, e.g.), toupper('i') is either - İ (LATIN CAPITAL LETTER I WITH DOT ABOVE; if representable) or - i (unchanged; if it isn't) Both results are wrong for the present use-case. Fix by adding QtMiscTools::toAsciiUpper(), complementing existing toAsciiLower(), and using that. It's private API, but moc.h, despite the name, is not a public header. Task-number: QTBUG-109235 Change-Id: Iaf071ba2113b672aa0aed3da6a4e1d47fb659365 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit b8c2a0c18a0676595946b5543ff88492a5fc7876) Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
| * [docs] QList: fix history of clear() semantics changeMarc Mutz2022-11-281-10/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | The description was copied from QVector, and doesn't exactly fit QList. For QList, the behavior changed in Qt 6.0 when QList became QVector, not in Qt 5.7, as indicated. Be more precise. Change-Id: I4029d83128ec205f628125d78394e8ee79cc221f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 13293d3308c04d22bc2928e8991f47744560e085) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* | Merge remote-tracking branch 'origin/tqtc/lts-6.2.7' into ↵Tarja Sundqvist2023-10-034-20/+54
|\| | | | | | | | | | | tqtc/lts-6.2-opensource Change-Id: Ie70d33341cccaaa69968dc8d1337ec27d7895127
| * Documentation: Fix information on how to iterate over listsFriedemann Kleint2022-11-251-15/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | Remove the outdated code used for QStringList and point QStringList and QList to the containers page. Task-number: QTBUG-108687 Change-Id: I6fae6410ca759f91da85832ddb9f24e8a0ce202b Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 4a6ce541c59cfaabb5c68066d0e19912032e48df) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
| * Q(Multi)Map: prevent dangling key/value after detach()Giuseppe D'Angelo2022-11-171-3/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Q(Multi)Map mutating functions that take reference to a key and/or a value (e.g. insert(), take(), etc.) must make sure that those references are still valid -- that is, that the referred objects are still alive -- after the detach() call done inside those functions. In fact, if the key/value are references into *this, one must take extra steps in order to preserve them across the detach(). Consider the scenario where one has two shallow copies of QMap, each accessed by a different thread, and each thread calls a mutating function on its copy, using a reference into the map (e.g. map.take(map.firstKey())). Let's call the shared payload of this QMap SP, with its refcount of 2; it's important to note that the argument (call it A) passed to the mutating function belongs to SP. Each thread may then find the reference count to be different than 1 and therefore do a detach() from inside the mutating function. Then this could happen: Thread 1: Thread 2: detach() detach() SP refcount != 1 => true SP refcount != 1 => true deep copy from SP deep copy from SP ref() the new copy ref() the new copy SP.deref() => 1 => don't dealloc SP set the new copy as payload SP.deref() => 0 => dealloc SP set the new copy as payload use A to access the new copy use A to access the new copy The order of ref()/deref() SP and the new copy in each thread doesn't really matter here. What really matters is that SP has been destroyed and that means A is a danging reference. Fix this by keeping SP alive in the mutating functions before doing a detach(). This can simply be realized by taking a local copy of the map from within such functions. remove() doesn't suffer from this because its implementation doesn't do a bare detach() but something slightly smarter. Change-Id: Iad974a1ad1bd5ee5d1e9378ae90947bef737b6bb Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> (cherry picked from commit 8c9875893bbd7b1355e36d9501d8cb1f84cb6b4d) Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
| * QTaggedPointer: disable operator= with an empty initializer listGiuseppe D'Angelo2022-10-111-2/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Given a QTaggedPointer, users may write taggedPtr = {}; to mean "reset it". This is error-prone: due to overload resolution, this actually ends up calling QTaggedPointer<T>::operator=(T *), which changes the pointer but *not* the tag, and not the implicitly declared QTaggedPointer<T>:operator=(const QTaggedPointer<T> &) which would reset both pointer and tag. Given the idiomatic usage of {} is indeed to perform a full reset (cf. std::exchange(obj, {}), std::take, etc.), work around this by disabling the operator= overload for pointers in case an initializer list is passed. In other words, make `={}` fall back to the implicitly declared overload. Note, this breaks some usages, such as taggedPtr = {rawPtr}; but at least we get a compile error for these, and they don't look common at all. [ChangeLog][QtCore][QTaggedPointer] The operator assignment taking a raw pointer has been reimplemented in order to avoid subtle issues when assigning `{}` to a QTaggedPointer. This will cause code that assigns a braced-init-list to a QTaggedPointer object to stop compiling (for instance, `tagPtr = {ptr}` is now ill-formed). Change-Id: I5e572a9b0f119ddb2df17f1797934933dff2ba7b Task-number: QTBUG-106070 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 42b66bd809f0cadf232cd8527746b55cd00d9f10) Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
| * [docs] QMap: fix missing toStdMap()&& overload docsMarc Mutz2022-10-111-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Amends 14090760a87f23509b7bb5ad846537c766cb44a5. I tried to find a linkable definition of valid-but-unspecified on en.cppreference.com, but failed, so I'm using partially-formed like everywhere else in Qt docs. Ideally, we'd have the discussion of partially-formed (and valid-but-unspecified) in some extra page and simply link to it. Created QTBUG-106251 to track the issue. Change-Id: I04c60cf903b2617c89467d1d040d5aebb7eccd53 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 3cd9536b7f6224b1c8fea2e40afdb5fe7b441f82) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* | Merge remote-tracking branch 'origin/tqtc/lts-6.2.6' into ↵Tarja Sundqvist2023-03-012-4/+2
|\| | | | | | | | | | | tqtc/lts-6.2-opensource Change-Id: I498f628eea18ec7b5fa3f14c12bb953f0d13663c
| * QOffsetStringArray: fix ambiguous qOffsetStringArray overloadsMarc Mutz2022-09-111-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are two qOffsetStringArray overloads: one in QT_NAMESPACE, the other in QT_PREPEND_NAMESPACE(QtPrivate). In TUs which use using namespace QtPrivate, a call to qOffsetStringArray() may become ambiguous. Fix by renaming the qOffsetStringArray() to makeOffsetStringArray(). Manual conflict resolutions: - the code is completely different in 6.2, but there are still a public and a private overload of qOffsetStringArray, so simply re-did the change on top of the old code. Change-Id: I242a969f363e230d6a8dfb048601a0c024724f6a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 21c5eeba673694f865badfd137ee9fc474177ae0) Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
| * QtBase: eradicate QT_STRINGVIEW_LEVEL usesMarc Mutz2022-08-051-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It's not used and not useful. The macro itself has to stay, for now, because Qt5Compat uses it, too. Conflicts: - qlocale.h - qlocale.cpp - qstring.h Task-number: QTBUG-100861 Change-Id: I5d0557a6c959d6facf6e47f26786a9d365339e95 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 16c453069f7b44ba7328a178b4b9ce99a150813e)
* | Revert "Update commercial license headers"v6.2.5-lts-lgplTarja Sundqvist2022-11-2475-1589/+1589
|/ | | | | | | | | | | This reverts commit 90c32995096ae90eb3c6f2da407488c5c063657f. Revert of commercial license headers is required for the Qt 6.2.x opensource releases, Qt 6.2.5 onwards. Task-number: QTBUG-107760 Change-Id: I80c7825f97af6eab576916514c2179840eb41fd3 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Update commercial license headersTarja Sundqvist2022-06-2175-1589/+1589
| | | | | | | | | | | | | | | Updated header.COMM to the files in tqtc-qtbase. Examples, tests, or documentation files are not updated. The commercial license header may contain some additional lines so that its line count equals with the earlier license header. Reason for this is that some autotests use hard coded line numbers and a change in the line count causes failures in tests. Task-number: QTQAINFRA-4934 Change-Id: Ie60b1b5f64c28ddcc77462abadbcf66af7c6d73b Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QMap: remove more docs referring to multiple values for the same keyGiuseppe D'Angelo2022-06-031-21/+4
| | | | | | | | | Such semantics have been dropped from Qt 6. Change-Id: I12f3478833afafa34f9075faf9ed030d06cd86f9 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit f69005687c333741925a437ffbea3cec24c0d46b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QMap: fix values() documentationGiuseppe D'Angelo2022-06-031-3/+1
| | | | | | | | | | The body was still referring to the Qt 5 QMap where the same key could be mapping to multiple values. That's no longer the case in Qt 6. Change-Id: Idb1786ac45f328c318878fa52bf5d43d79c0178a Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit e4f2f0e125d20f3134fc28af42034ff1806d8141) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QVector: make sure the forwarding headers for the Java iterators existThiago Macieira2022-06-031-0/+6
| | | | | | | | | | | | | | | They used to in Qt 5. And now they do again: $ grep . include/QtCore/Q*Vector* include/QtCore/QMutableVectorIterator:#include "qvector.h" include/QtCore/QVector:#include "qvector.h" include/QtCore/QVectorIterator:#include "qvector.h" Fixes: QTBUG-103742 Change-Id: I77c8221eb2824c369feffffd16f128a983f4866c Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 34cb03da89188c8c6566681a2c2548731b007099) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* Add a few explicit conversions back from intThiago Macieira2022-06-012-3/+3
| | | | | | | | | | | | Suppresses GCC's -Wconversion, which is not enabled by default. error: conversion from ‘int’ to ‘quint8’ {aka ‘unsigned char’} may change value [-Werror=conversion] Change-Id: I0e5f6bec596a4a78bd3bfffd16c998102bd51f7c Fixes: QTBUG-103001 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 214df31916c53e46348173fc02fe53f2b9db729a)
* QHash: port away from std::aligned_storageMarc Mutz2022-05-311-1/+1
| | | | | | | | | | | | It's deprecated in C++23. Just use an explicitly-aligned char array directly, wrapped in a struct to avoid decays to char*. Task-number: QTBUG-99122 Change-Id: I802761c1af62efa6ffc006b07837a7deed1ea4cc Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit d8e03bb02d93f9eb843923063c13162ce10079e0) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* Use Q_CC_{GNU,MSVC}_ONLY when comparing to particular versionsMarc Mutz2022-05-312-3/+3
| | | | | | | | | | | | | | | | | | | | | | This prevents false-negatives and false-positives, as e.g. Clang 10.0.0 masks as GCC 4.2, so Q_CC_GNU is 402 on that compiler. Depending on the test (Q_CC_GNU > NNN or Q_CC_GNU < NNN), the result of the test is almost random. Q_CC_<comp>_ONLY makes sure we match only GCC or MSVC, not bycatch such as Clang or ICC. Manual conflict resolutions: - dropped change around Q_CONSTINIT, which doesn't exist < 6.4 - rebased past conflicting change f11bc388508359b070320866eab4c917cb4c4739 Change-Id: I4c550a11ecf85fc9a2216b330b69bd03d45b47e0 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> (cherry picked from commit cdd4a953171d1d4d897b3affd2fd944fcff37f68)
* Q[Multi]Hash: fix squeeze()Ivan Solovev2022-04-061-14/+29
| | | | | | | | | | | | | | | | | | | | When calling QHash::reserve(), or when creating the internal QHashPrivate::Data structure, the value 0 for the size parameter is reserved for performing the squeeze operation. However commit 8a984ab772dd194e39094e728b869e65912912a7 broke it, by using the 0 value in QHashPrivate::Data constructors as a mark that no resizing needs to be done. This patch reverts the problematic commit (also applying some later fixes to the code), and adds the missing tests for Q[Multi]Hash::squeeze(). Change-Id: Id644df7b2beb008e6a37b2c89b709adfbd893e25 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 7c9afa8d00cc2bbc1b102eef6e76c23e07c7833f) Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Q[Multi]Hash::reserve(): do nothing if desired size is less than currentIvan Solovev2022-04-061-0/+6
| | | | | | | | | | | | | | | | | Calling Q[Multi]Hash::reserve(n) when n is much smaller than the current amount of elements in the hash, could result in an infinite loop, because at some point the algorithm could not find a free bucket for the element. Fixing it by returning early if the new desired capacity is less than current. Fixes: QTBUG-102067 Change-Id: I38ef0b2168c4e2a317eedf91b2155b1fdffb1c27 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit d11941db41f00525f907417bbcd6ac5ee30d8485) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QMargins: fix a missing "full stop" in the docsMarc Mutz2022-03-191-1/+1
| | | | | | | Change-Id: Ic8012ce12ef8d2fee2dc785e373e9c9d8f658ff5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 98cbdae527b360e0e6d630848a375c6a025f572d) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QVersionNumber: remove the "pure" attribute from commonPrefix()Thiago Macieira2022-03-161-1/+1
| | | | | | | | | This function can allocate memory, so it's not pure. Change-Id: I6fcda969a9e9427198bffffd16ce7fcff3ae021d Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 671035035a6f1846c05e052e4e745d5cb2b41306) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QWeakPointer: befriend other QWeakPointersThiago Macieira2022-03-071-2/+3
| | | | | | | | | | | Commit c677b3b8afcdc1d7b57353826cc01f378cd25e99 added move constructors, which introduced the issue. Fixes: QTBUG-100795 Change-Id: I74249c52dc02478ba93cfffd16d2c879b923e352 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> (cherry picked from commit 49722de99527a97373df517dcb457f3170693a4f) Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Backport QtMiscUtils::toAsciiLower() from devMarc Mutz2022-03-041-0/+5
| | | | | | | | | | | | A partial cherry-pick of 5f338040f4ecbf6404ea5610ec19adfd9ca71c35, it contains only the new helper function, making it available for cherry-picking 955106c4fbc3769c646beb99ed91dadff14ec2d2. Change-Id: Iea89ac12cf2f0fcf94efba69ba94f92f4e3e0fed Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 04cc5befd67e78ed90f4632532e8ca1dfd43675b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QHash: fix off-by-one in assertionsMårten Nordheim2022-02-161-6/+6
| | | | | | | | | | | | | Coverity-Id: 378365 Coverity-Id: 378366 Coverity-Id: 378399 Coverity-Id: 378427 Coverity-Id: 378468 Coverity-Id: 378472 Change-Id: Ib1efeacb59030b9d004320e56f560367f564d207 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit a1fb3971f222afa01583e41f4d8f0e037d2c7892)
* QHashSeed: remove 'pure' attribute on globalSeed()Marc Mutz2022-02-121-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While 'pure' in GCC is weaker than Stepanov's Regular Procedure from Elements of Programming (equal result for equal inputs), it does not allow accesses to volatile memory: > functions declared with the pure attribute can safely read any > non-volatile objects The globalSeed() function reads from an atomic variable that can be changed at any time from another thread. Atomics, while not volatile objects in the sense of the keyword, must fall under the pure attribute doc's exclusion criterion: The difference between a volatile and an atomic access, while important for the implementation of the function, is indistinguishable to the caller of the function: both volatile and atomic objects can change value without the current thread of execution changing them, with no way for the caller of the function to distinguish which one occurred. Therefore, globalSeed() should not be pure. 5.15 is not affected, as qGlobalQHashSeed() is not marked as pure. Task-number: QTBUG-62185 Change-Id: I6fc52e2bd41ef4aa3f8039072b47c7a1314b98fa Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit c8e03f129ea52ddc8e15104d5441328f6c90647f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QFreeList: replace a Q_ASSERT(false) with Q_UNREACHABLE()Thiago Macieira2022-02-101-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Q_ASSERT goes away in release builds, Q_UNREACHABLE() does not. This also solves the GCC 12 warning about out-of-bounds access in QAbstractEventDispatcherPrivate::allocateTimerId(): In member function ‘_PTp* std::__atomic_base<_PTp*>::load(std::memory_order) const [with _PTp = QFreeListElement<void>]’, inlined from ‘_Tp* std::atomic<_Tp*>::load(std::memory_order) const [with _Tp = QFreeListElement<void>]’ at atomic:579:25, inlined from ‘static T QAtomicOps<X>::loadAcquire(const std::atomic<T>&) [with T = QFreeListElement<void>*; X = QFreeListElement<void>*]’ at thread/qatomic_cxx11.h:249:29, inlined from ‘X* QBasicAtomicPointer<X>::loadAcquire() const [with X = QFreeListElement<void>]’ at thread/qbasicatomic.h:233:64, inlined from ‘int QFreeList<T, ConstantsType>::next() [with T = void; ConstantsType = QtTimerIdFreeListConstants]’ at qfreelist_p.h:245:34, inlined from ‘static int QAbstractEventDispatcherPrivate::allocateTimerId()’ at kernel/qabstracteventdispatcher.cpp:99:24: bits/atomic_base.h:820:31: warning: ‘long unsigned int __atomic_load_8(const volatile void*, int)’ writing 8 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=] 820 | return __atomic_load_n(&_M_p, int(__m)); | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~ In file included from qglobalstatic.h:1, from qglobal.h:1395: qglobalstatic.h: In static member function ‘static int QAbstractEventDispatcherPrivate::allocateTimerId()’: qglobalstatic.h:127:23: note: at offset -8 into destination object ‘holder’ of size 56 127 | static Holder holder; | ^~~~~~ Change-Id: I74249c52dc02478ba93cfffd16d232b275d5d216 Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit dcdb8884e732802c92ae96b6d5b21331ddaef55b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* Sequential erase/_if: don't apply predicate twice to elementMarc Mutz2022-02-021-25/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The code was trying to avoid a detach in the case no element needed to be removed, by first running find_if() on const_iterators, and then, after converting its result to (mutable) iterators, start the remove_if() algorithm where find_if() left off. But this applies the predicate to the element found by find_if() (if any) _twice_: first just before we exit the first find_if() and then just as we enter remove_if(), which will start by running find_if() again, with the result of the initial find_if as 'first'. Apart from being needlessly inefficient, this violates the specification of Uniform Erasure, which defines sequential erase_if() as being equivalent to remove_if() + container erase(), with the former being specified to apply the predicate exactly once per element. Fix by writing the remove_if() part by hand. Instead of doing the dance with the loop invariant documentation twice, simply implement erase() via erase_if() (complicated a bit by the weird passing of predicates by lvalue reference instead of by value, as would be idiomatic). This exposes users to: [ChangeLog][QtCore][Potentially Source-Incompatible Changes] A fix in the implementation of the erase-like algorithms of sequential Qt container may re-enable signed/unsigned comparison warnings previously suppressed by having occurred in std library code. To fix, cast the value to look for such that it has the same signedness as the container's elements. ... but the issue would be the same had we inlined std::remove() instead of passing a lambda to sequential_erase_if(), so it's nothing we can, nor should, work around. [ChangeLog][QtCore][Containers] Fixed a bug in the implementation of most sequential Qt container's erase-like algorithms (member removeAll()/removeIf() and free erase()/erase_if()) where the equality operator or the predicate, respectively, was applied to the first matching element twice. Each element is now tested exactly once. Change-Id: Ib6d24b01b40866c125406f1cd6042d4cd083ea0d Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> (cherry picked from commit 9f31f579ec2e6f15c6c87b0e3c5c762ea2690bc9) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QWeakPointer: make default ctor constexprMarc Mutz2022-02-011-1/+1
| | | | | | | | | | | ... and thereby also QPointer's. Found by applying C++20 constinit around the codebase. Change-Id: I9f149b2346624ca913c29b796f94ac7d24fe560a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit aaa74e8f99c91bb877e5f3a8ee4a8b313d2fa133) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QVersionNumber: remove "pure" declaration from fromString()Thiago Macieira2022-01-291-3/+3
| | | | | | | | | | | | | | GCC doesn't like that we modify the contents of passed by pointer in the pure function. Reading the description of this attribute in the GCC manual was ambiguous then, but I can see the GCC maintainers' interpretation. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104243 Fixes: QTBUG-62185 Change-Id: I6fcda969a9e9427198bffffd16cdf815d059d252 Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 77923604130057261bf774b5cc32d849a595a1f0)
* QFlatMap: use erase() in remove()Marc Mutz2022-01-281-2/+1
| | | | | | | | | | | De-duplicates code. Change-Id: I95d3d6f57c2f3716b8f3f549d1cc2a02cde9e996 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit d030606a5a6c9c30972892f94ac656e983183349) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QFlatMap: replace manual const_cast<>s with std::as_constMarc Mutz2022-01-281-9/+7
| | | | | | | | | | | | | | | Shorter, because it doesn't need to name the type. As a drive-by, replace all remaining uses of the private full_map_t alias with 'QFlatMap', the class name, which, also in templates, refers to the class, not the class template. Change-Id: Ie3bada43d9d28a84543e8baa8a36c522dff80b9e Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit 1cb192bf3da88c97e7622d4813053a4ca916044e) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QtCore: replace qSwap with std::swap/member-swap where possibleMarc Mutz2022-01-2015-26/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | qSwap() is a monster that looks for ADL overloads of swap() and also detects the noexcept of the wrapped swap() function, so it should only be used when the argument type is unknown. In the vast majority of cases, the type is known to be efficiently std::swap()able or to have a member-swap. Call either of these. For the common case of pointer types, circumvent the expensive trait checks on std::swap() by providing a hand-rolled qt_ptr_swap() template, the advantage being that it can be unconditionally noexcept, removing all type traits instantiations. Don't document it, otherwise we'd be unable to pick it to 6.2. Effects on Clang -ftime-trace of a PCH'ed libQt6Gui.so build: before: **** Template sets that took longest to instantiate: [...] 27766 ms: qSwap<$> (9073 times, avg 3 ms) [...] 2806 ms: std::swap<$> (1229 times, avg 2 ms) (30572ms) after: **** Template sets that took longest to instantiate: [...] 5047 ms: qSwap<$> (641 times, avg 7 ms) [...] 3371 ms: std::swap<$> (1376 times, avg 2 ms) [qt_ptr_swap<$> does not appear in the top 400, so < 905ms] (< 9323ms) As a drive-by, remove superfluous inline keywords and template ornaments. Task-number: QTBUG-97601 Change-Id: I88f9b4e3cbece268c4a1238b6d50e5712a1bab5a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit b1b0c2970e480ef460a61f37fa430dc443390358) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QVersionNumber: don't detach() in rvalue QList/QVector ctorMarc Mutz2022-01-191-2/+2
| | | | | | | | | | | | | Qt 5 and 6.2 use begin() so the fix there will be to use cbegin(). Found by Clang -ftime-trace pin-pointing repeated instantiations of QList<int>::data(). Task-number: QTBUG-97601 Change-Id: I6410e5b303766fdbc7e158a9ac1263adec973099 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 552d1c91669ac22006a9ccc3146efb4c4f2c49d6) Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QCache: fix potential crash in trim()Mårten Nordheim2022-01-151-5/+3
| | | | | | | | | | | | | | | | | | We use raw pointers to the Nodes in the QHash which is inherently fine, but we are then subject to invalidation when nodes are moved around during deletion. In trim() we don't actually need to iterate the linked-list since the node we are interested in is always chain.prev Fixes: QTBUG-99710 Task-number: QTBUG-99224 Task-number: QTBUG-99240 Change-Id: I9c2ed69b29e3cadca013113a3553deb44d7382fc Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> (cherry picked from commit 8c5e31536ac74f643d4dd371d281fd9416864a45) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QFlatMap: don't sort already ordered dataMarc Mutz2022-01-151-1/+1
| | | | | | | | Change-Id: Id7ab2fe09c01500ca5bd23751ba29ed1394bb9b6 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit afdcb64ccd4af726d1f078ab7c5f28249fa04724) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QFlatMap: add insert_or_assignMarc Mutz2022-01-141-0/+18
| | | | | | | | | | | | | | | | | This does exactly what insert() on Qt associative containers does, but allows to express the intent of using the STL-incompatible Qt insert() semantics, in an STL-compatible way, instead of leaving the reader of the code wondering what semantics are expected. This is part of a very-long-term goal of fixing Qt associative container's insert() behavior, in which QFlatMap, being an affected, but private-API type, is used for proof-of-concept purposes. Task-number: QTBUG-99651 Change-Id: I69010285438259918aef659d3235180c1b5be696 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit 6891e10f9717a51b72583bf18e5a1a8d5f5fd527) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QFlatMap: add try_emplace (w/o hint)Marc Mutz2022-01-121-0/+24
| | | | | | | | | | | | | | | | | | | | | | | QFlatMap, like its public brethren, features the broken Qt-style insert() behavior (what the STL calls insert_or_assign()), which makes its insert() unusable for actual STL-style insert() work, with no replacement except the size-check-and-index-operator trick: const auto oldSize = c.size(); auto &e = c[key]; if (c.size() != oldSize) { // inserted } Even though QFlatMap::insert() appears to return the correct info, it's useless, because the old value has been assigned over by the time insert() returns. Change-Id: If4173c42523a128dfd22ab496dde0089ba73f41c Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit f044664c685eb81205c2ebdd78e11367d2d44006) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QFlatMap: optimize construction from existing containersMarc Mutz2022-01-121-14/+7
| | | | | | | | | | Use {copy,move} ctors instead of default-ctor, followed by (move|copy)-assignment. Change-Id: Id2fd53050cd353a9374fd065ac25d753d42d1be9 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit 3917838d64a39186f5b4eedbd55347e445ca2aec) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QFlatMap: add an alias for using QVarLengthArraysMarc Mutz2022-01-121-0/+3
| | | | | | | | | | | ... in an attempt to foster the use of this data structure by making it less onerous to spell. Change-Id: Ib9d17029c75278edde6ba90f65f68af179a6d230 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io> (cherry picked from commit d4611ba3a5b46ee790e6c790ef6c3d771d3507ee) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* QFlatMap: fix pointless reallocations on repeated range-insert()sMarc Mutz2022-01-121-2/+0
| | | | | | | | | | | | | When looping over range-insert(), the repeated shrink_to_fit() calls would cause cause reserved (or geometrically-grown) capacity to be shed, breaking the underlying container's growth strategy. Fix by not shedding excess capacity. Change-Id: I10915a06fc9442039c192486a55e48083da7c839 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit e809d4e3ccdb713407253150d82d8634dc3cf97e) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>