diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/configure.json | 2 | ||||
-rw-r--r-- | src/corelib/global/qcompilerdetection.h | 1 | ||||
-rw-r--r-- | src/corelib/global/qfloat16_f16c.c | 11 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 12 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 24 | ||||
-rw-r--r-- | src/corelib/io/qabstractfileengine.cpp | 8 | ||||
-rw-r--r-- | src/corelib/itemmodels/qsortfilterproxymodel.cpp | 54 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_mac.mm | 10 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_mac_p.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qeventloop.cpp | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 4 | ||||
-rw-r--r-- | src/corelib/mimetypes/qmimeglobpattern.cpp | 108 | ||||
-rw-r--r-- | src/corelib/mimetypes/qmimeglobpattern_p.h | 19 | ||||
-rw-r--r-- | src/corelib/mimetypes/qmimeprovider.cpp | 1 | ||||
-rw-r--r-- | src/corelib/statemachine/qstatemachine.cpp | 5 | ||||
-rw-r--r-- | src/corelib/text/qregularexpression.cpp | 8 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 2 | ||||
-rw-r--r-- | src/corelib/tools/qvarlengtharray.h | 19 | ||||
-rw-r--r-- | src/corelib/tools/qvector.h | 27 |
19 files changed, 234 insertions, 88 deletions
diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 74c7181dd1..a9025a2dd2 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -355,7 +355,7 @@ "std::future<int> f = std::async([]() { return 42; });", "(void)f.get();" ], - "qmake": "unix:LIBS += -lpthread" + "qmake": "unix:!vxworks:LIBS += -lpthread" } }, "cxx11_random": { diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index ebffe74188..412fea96b4 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1371,6 +1371,7 @@ # undef QT_COMPILER_SUPPORTS_SSE4_2 # undef QT_COMPILER_SUPPORTS_AVX # undef QT_COMPILER_SUPPORTS_AVX2 +# undef QT_COMPILER_SUPPORTS_F16C #endif #if !defined(Q_PROCESSOR_ARM) # undef QT_COMPILER_SUPPORTS_NEON diff --git a/src/corelib/global/qfloat16_f16c.c b/src/corelib/global/qfloat16_f16c.c index ba1e16f481..d60a021bdb 100644 --- a/src/corelib/global/qfloat16_f16c.c +++ b/src/corelib/global/qfloat16_f16c.c @@ -40,13 +40,8 @@ #include "private/qsimd_p.h" // The x86 F16C instructions operate on AVX registers, so AVX support is -// required. We don't need to check for __F16C__ because we this file wouldn't -// have been compiled if the support was missing in the first place, and not -// all compilers define it. Technically, we didn't need to check for __AVX__ -// either. -#if !QT_COMPILER_SUPPORTS_HERE(AVX) -# error "AVX support required" -#endif +// required. +#if QT_COMPILER_SUPPORTS_HERE(AVX) #ifdef __cplusplus QT_BEGIN_NAMESPACE @@ -89,3 +84,5 @@ void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) Q_DECL } // extern "C" QT_END_NAMESPACE #endif + +#endif // QT_COMPILER_SUPPORTS_HERE(AVX) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index fd8319aae0..ac2e85c51e 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2264,7 +2264,17 @@ static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSyst case Q_WINVER(6, 3): return workstation ? "8.1" : "Server 2012 R2"; case Q_WINVER(10, 0): - return workstation ? "10" : "Server 2016"; + if (workstation) { + if (osver.dwBuildNumber >= 22000) + return "11"; + return "10"; + } + // else: Server + if (osver.dwBuildNumber >= 20348) + return "Server 2022"; + if (osver.dwBuildNumber >= 17763) + return "Server 2019"; + return "Server 2016"; } #undef Q_WINVER // unknown, future version diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 12ac48f3cb..450c1e586a 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1102,13 +1102,16 @@ QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t) } +#define Q_FOREACH_JOIN(A, B) Q_FOREACH_JOIN_IMPL(A, B) +#define Q_FOREACH_JOIN_IMPL(A, B) A ## B + #if __cplusplus >= 201703L // Use C++17 if statement with initializer. User's code ends up in a else so // scoping of different ifs is not broken -#define Q_FOREACH(variable, container) \ -for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ - _container_.i != _container_.e; ++_container_.i) \ - if (variable = *_container_.i; false) {} else +#define Q_FOREACH_IMPL(variable, name, container) \ + for (auto name = QtPrivate::qMakeForeachContainer(container); \ + name.i != name.e; ++name.i) \ + if (variable = *name.i; false) {} else #else // Explanation of the control word: // - it's initialized to 1 @@ -1119,12 +1122,15 @@ for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ // the outer loop to continue executing // - if there was a break inside the inner loop, it will exit with control still // set to 1; in that case, the outer loop will invert it to 0 and will exit too -#define Q_FOREACH(variable, container) \ -for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ - _container_.control && _container_.i != _container_.e; \ - ++_container_.i, _container_.control ^= 1) \ - for (variable = *_container_.i; _container_.control; _container_.control = 0) +#define Q_FOREACH_IMPL(variable, name, container) \ +for (auto name = QtPrivate::qMakeForeachContainer(container); \ + name.control && name.i != name.e; \ + ++name.i, name.control ^= 1) \ + for (variable = *name.i; name.control; name.control = 0) #endif + +#define Q_FOREACH(variable, container) \ + Q_FOREACH_IMPL(variable, Q_FOREACH_JOIN(_container_, __LINE__), container) #endif // QT_NO_FOREACH #define Q_FOREVER for(;;) diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index 070139b608..ef6e91d826 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -101,7 +101,7 @@ QT_BEGIN_NAMESPACE \sa QAbstractFileEngine, QAbstractFileEngine::create() */ -static bool qt_file_engine_handlers_in_use = false; +static QBasicAtomicInt qt_file_engine_handlers_in_use = Q_BASIC_ATOMIC_INITIALIZER(false); /* All application-wide handlers are stored in this list. The mutex must be @@ -132,7 +132,7 @@ Q_GLOBAL_STATIC(QAbstractFileEngineHandlerList, fileEngineHandlers) QAbstractFileEngineHandler::QAbstractFileEngineHandler() { QWriteLocker locker(fileEngineHandlerMutex()); - qt_file_engine_handlers_in_use = true; + qt_file_engine_handlers_in_use.storeRelaxed(true); fileEngineHandlers()->prepend(this); } @@ -148,7 +148,7 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandler() QAbstractFileEngineHandlerList *handlers = fileEngineHandlers(); handlers->removeOne(this); if (handlers->isEmpty()) - qt_file_engine_handlers_in_use = false; + qt_file_engine_handlers_in_use.storeRelaxed(false); } } @@ -161,7 +161,7 @@ QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path) { QAbstractFileEngine *engine = nullptr; - if (qt_file_engine_handlers_in_use) { + if (qt_file_engine_handlers_in_use.loadRelaxed()) { QReadLocker locker(fileEngineHandlerMutex()); // check for registered handlers that can load the file diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 1abdafcdbe..dc6379d9fb 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -307,6 +307,8 @@ public: QHash<QModelIndex, Mapping *>::const_iterator create_mapping( const QModelIndex &source_parent) const; + QHash<QModelIndex, Mapping *>::const_iterator create_mapping_recursive( + const QModelIndex &source_parent) const; QModelIndex proxy_to_source(const QModelIndex &proxyIndex) const; QModelIndex source_to_proxy(const QModelIndex &sourceIndex) const; bool can_create_mapping(const QModelIndex &source_parent) const; @@ -533,6 +535,29 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping( return it; } +// Go up the tree, creating mappings, unless of course the parent is filtered out +IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping_recursive(const QModelIndex &source_parent) const +{ + if (source_parent.isValid()) { + const QModelIndex source_grand_parent = source_parent.parent(); + IndexMap::const_iterator it = source_index_mapping.constFind(source_grand_parent); + IndexMap::const_iterator end = source_index_mapping.constEnd(); + if (it == end) { + it = create_mapping_recursive(source_grand_parent); + end = source_index_mapping.constEnd(); + if (it == end) + return end; + } + Mapping *gm = it.value(); + if (gm->proxy_rows.at(source_parent.row()) == -1 || + gm->proxy_columns.at(source_parent.column()) == -1) { + // Can't do, parent is filtered + return end; + } + } + return create_mapping(source_parent); +} + QModelIndex QSortFilterProxyModelPrivate::proxy_to_source(const QModelIndex &proxy_index) const { if (!proxy_index.isValid()) @@ -751,8 +776,10 @@ void QSortFilterProxyModelPrivate::remove_source_items( { Q_Q(QSortFilterProxyModel); QModelIndex proxy_parent = q->mapFromSource(source_parent); - if (!proxy_parent.isValid() && source_parent.isValid()) + if (!proxy_parent.isValid() && source_parent.isValid()) { + proxy_to_source.clear(); return; // nothing to do (already removed) + } const auto proxy_intervals = proxy_intervals_for_source_items( source_to_proxy, source_items); @@ -1404,11 +1431,20 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc const QModelIndex &source_bottom_right = data_changed.bottomRight; const QModelIndex source_parent = source_top_left.parent(); + bool change_in_unmapped_parent = false; IndexMap::const_iterator it = source_index_mapping.constFind(source_parent); if (it == source_index_mapping.constEnd()) { - // Don't care, since we don't have mapping for this index - continue; + // We don't have mapping for this index, so we cannot know how things + // changed (in case the change affects filtering) in order to forward + // the change correctly. + // But we can at least forward the signal "as is", if the row isn't + // filtered out, this is better than nothing. + it = create_mapping_recursive(source_parent); + if (it == source_index_mapping.constEnd()) + continue; + change_in_unmapped_parent = true; } + Mapping *m = it.value(); // Figure out how the source changes affect us @@ -1418,7 +1454,7 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc QVector<int> source_rows_resort; int end = qMin(source_bottom_right.row(), m->proxy_rows.count() - 1); for (int source_row = source_top_left.row(); source_row <= end; ++source_row) { - if (dynamic_sortfilter) { + if (dynamic_sortfilter && !change_in_unmapped_parent) { if (m->proxy_rows.at(source_row) != -1) { if (!filterAcceptsRowInternal(source_row, source_parent)) { // This source row no longer satisfies the filter, so it must be removed @@ -1568,7 +1604,6 @@ void QSortFilterProxyModelPrivate::_q_sourceReset() _q_clearMapping(); // All internal structures are deleted in clear() q->endResetModel(); - create_mapping(QModelIndex()); update_source_sort_column(); if (dynamic_sortfilter && update_source_sort_column()) sort(); @@ -1634,8 +1669,8 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted( const bool toplevel = !source_parent.isValid(); const bool recursive_accepted = filter_recursive && !toplevel && filterAcceptsRowInternal(source_parent.row(), source_parent.parent()); - //Force the creation of a mapping now, even if its empty. - //We need it because the proxy can be acessed at the moment it emits rowsAboutToBeInserted in insert_source_items + //Force the creation of a mapping now, even if it's empty. + //We need it because the proxy can be accessed at the moment it emits rowsAboutToBeInserted in insert_source_items if (!filter_recursive || toplevel || recursive_accepted) { if (can_create_mapping(source_parent)) create_mapping(source_parent); @@ -1754,8 +1789,8 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted( { Q_UNUSED(start); Q_UNUSED(end); - //Force the creation of a mapping now, even if its empty. - //We need it because the proxy can be acessed at the moment it emits columnsAboutToBeInserted in insert_source_items + //Force the creation of a mapping now, even if it's empty. + //We need it because the proxy can be accessed at the moment it emits columnsAboutToBeInserted in insert_source_items if (can_create_mapping(source_parent)) create_mapping(source_parent); } @@ -2149,7 +2184,6 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); endResetModel(); - d->create_mapping(QModelIndex()); if (d->update_source_sort_column() && d->dynamic_sortfilter) d->sort(); } diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm index 7d696364e2..e774cebcbf 100644 --- a/src/corelib/kernel/qcore_mac.mm +++ b/src/corelib/kernel/qcore_mac.mm @@ -54,6 +54,7 @@ #include <cxxabi.h> #include <objc/runtime.h> #include <mach-o/dyld.h> +#include <sys/sysctl.h> #include <qdebug.h> @@ -351,6 +352,15 @@ bool qt_mac_applicationIsInDarkMode() #endif return false; } + +bool qt_mac_runningUnderRosetta() +{ + int translated = 0; + auto size = sizeof(translated); + if (sysctlbyname("sysctl.proc_translated", &translated, &size, nullptr, 0) == 0) + return translated; + return false; +} #endif bool qt_apple_isApplicationExtension() diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 96a2ff8567..a851c3e742 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -172,6 +172,7 @@ private: Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key); Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode); Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode(); +Q_CORE_EXPORT bool qt_mac_runningUnderRosetta(); #endif #ifndef QT_NO_DEBUG_STREAM diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index dc53af7018..5d793ce72a 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -50,6 +50,9 @@ #ifdef Q_OS_WASM #include <emscripten.h> +#if QT_CONFIG(thread) +#include <emscripten/threading.h> +#endif #endif QT_BEGIN_NAMESPACE @@ -295,6 +298,9 @@ void QEventLoop::exit(int returnCode) // QEventLoop::exec() never returns in emscripten. We implement approximate behavior here. // QTBUG-70185 if (threadData->loopLevel == 1) { +#if QT_CONFIG(thread) + if (emscripten_is_main_browser_thread()) +#endif emscripten_force_exit(returnCode); } else { d->inExec = false; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c294868c62..1eb79138d9 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2333,6 +2333,10 @@ void QObject::removeEventFilter(QObject *obj) */ void QObject::deleteLater() { +#ifdef QT_DEBUG + if (qApp == this) + qWarning("You are deferring the delete of QCoreApplication, this may not work as expected."); +#endif QCoreApplication::postEvent(this, new QDeferredDeleteEvent()); } diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp index 1016884437..a81112d227 100644 --- a/src/corelib/mimetypes/qmimeglobpattern.cpp +++ b/src/corelib/mimetypes/qmimeglobpattern.cpp @@ -88,6 +88,40 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q } } +QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString &pattern) const +{ + const int patternLength = pattern.length(); + if (!patternLength) + return OtherPattern; + + const bool starCount = pattern.count(QLatin1Char('*')) == 1; + const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1; + const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1; + + if (!hasSquareBracket && !hasQuestionMark) { + if (starCount == 1) { + // Patterns like "*~", "*.extension" + if (pattern.at(0) == QLatin1Char('*')) + return SuffixPattern; + // Patterns like "README*" (well this is currently the only one like that...) + if (pattern.at(patternLength - 1) == QLatin1Char('*')) + return PrefixPattern; + } + // Names without any wildcards like "README" + if (starCount == 0) + return LiteralPattern; + } + + if (pattern == QLatin1String("[0-9][0-9][0-9].vdr")) + return VdrPattern; + + if (pattern == QLatin1String("*.anim[1-9j]")) + return AnimPattern; + + return OtherPattern; +} + + /*! \internal \class QMimeGlobPattern @@ -97,58 +131,66 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q \sa QMimeType, QMimeDatabase, QMimeMagicRuleMatcher, QMimeMagicRule */ -bool QMimeGlobPattern::matchFileName(const QString &inputFilename) const +bool QMimeGlobPattern::matchFileName(const QString &inputFileName) const { // "Applications MUST match globs case-insensitively, except when the case-sensitive // attribute is set to true." // The constructor takes care of putting case-insensitive patterns in lowercase. - const QString filename = m_caseSensitivity == Qt::CaseInsensitive ? inputFilename.toLower() : inputFilename; + const QString fileName = m_caseSensitivity == Qt::CaseInsensitive + ? inputFileName.toLower() : inputFileName; - const int pattern_len = m_pattern.length(); - if (!pattern_len) + const int patternLength = m_pattern.length(); + if (!patternLength) return false; - const int len = filename.length(); - - const int starCount = m_pattern.count(QLatin1Char('*')); + const int fileNameLength = fileName.length(); - // Patterns like "*~", "*.extension" - if (m_pattern[0] == QLatin1Char('*') && m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 1) - { - if (len + 1 < pattern_len) return false; + switch (m_patternType) { + case SuffixPattern: { + if (fileNameLength + 1 < patternLength) + return false; - const QChar *c1 = m_pattern.unicode() + pattern_len - 1; - const QChar *c2 = filename.unicode() + len - 1; + const QChar *c1 = m_pattern.unicode() + patternLength - 1; + const QChar *c2 = fileName.unicode() + fileNameLength - 1; int cnt = 1; - while (cnt < pattern_len && *c1-- == *c2--) + while (cnt < patternLength && *c1-- == *c2--) ++cnt; - return cnt == pattern_len; + return cnt == patternLength; } - - // Patterns like "README*" (well this is currently the only one like that...) - if (starCount == 1 && m_pattern.at(pattern_len - 1) == QLatin1Char('*')) { - if (len + 1 < pattern_len) return false; - if (m_pattern.at(0) == QLatin1Char('*')) - return filename.indexOf(m_pattern.midRef(1, pattern_len - 2)) != -1; + case PrefixPattern: { + if (fileNameLength + 1 < patternLength) + return false; const QChar *c1 = m_pattern.unicode(); - const QChar *c2 = filename.unicode(); + const QChar *c2 = fileName.unicode(); int cnt = 1; - while (cnt < pattern_len && *c1++ == *c2++) + while (cnt < patternLength && *c1++ == *c2++) ++cnt; - return cnt == pattern_len; + return cnt == patternLength; } - - // Names without any wildcards like "README" - if (m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 0 && m_pattern.indexOf(QLatin1Char('?'))) - return (m_pattern == filename); - - // Other (quite rare) patterns, like "*.anim[1-9j]": use slow but correct method + case LiteralPattern: + return (m_pattern == fileName); + case VdrPattern: // "[0-9][0-9][0-9].vdr" case + return fileNameLength == 7 + && fileName.at(0).isDigit() && fileName.at(1).isDigit() && fileName.at(2).isDigit() + && QStringView{fileName}.mid(3, 4) == QLatin1String(".vdr"); + case AnimPattern: { // "*.anim[1-9j]" case + if (fileNameLength < 6) + return false; + const QChar lastChar = fileName.at(fileNameLength - 1); + const bool lastCharOK = (lastChar.isDigit() && lastChar != QLatin1Char('0')) + || lastChar == QLatin1Char('j'); + return lastCharOK && QStringView{fileName}.mid(fileNameLength - 6, 5) == QLatin1String(".anim"); + } + case OtherPattern: + // Other fallback patterns: slow but correct method #if QT_CONFIG(regularexpression) - QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(m_pattern)); - return rx.match(filename).hasMatch(); + QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(m_pattern)); + return rx.match(fileName).hasMatch(); #else - return false; + return false; #endif + } + return false; } static bool isSimplePattern(const QString &pattern) diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h index 49f145e8db..88d032c787 100644 --- a/src/corelib/mimetypes/qmimeglobpattern_p.h +++ b/src/corelib/mimetypes/qmimeglobpattern_p.h @@ -80,7 +80,10 @@ public: explicit QMimeGlobPattern(const QString &thePattern, const QString &theMimeType, unsigned theWeight = DefaultWeight, Qt::CaseSensitivity s = Qt::CaseInsensitive) : m_pattern(s == Qt::CaseInsensitive ? thePattern.toLower() : thePattern), - m_mimeType(theMimeType), m_weight(theWeight), m_caseSensitivity(s) + m_mimeType(theMimeType), + m_weight(theWeight), + m_caseSensitivity(s), + m_patternType(detectPatternType(m_pattern)) { } @@ -90,9 +93,10 @@ public: qSwap(m_mimeType, other.m_mimeType); qSwap(m_weight, other.m_weight); qSwap(m_caseSensitivity, other.m_caseSensitivity); + qSwap(m_patternType, other.m_patternType); } - bool matchFileName(const QString &filename) const; + bool matchFileName(const QString &inputFileName) const; inline const QString &pattern() const { return m_pattern; } inline unsigned weight() const { return m_weight; } @@ -100,10 +104,21 @@ public: inline bool isCaseSensitive() const { return m_caseSensitivity == Qt::CaseSensitive; } private: + enum PatternType { + SuffixPattern, + PrefixPattern, + LiteralPattern, + VdrPattern, // special handling for "[0-9][0-9][0-9].vdr" pattern + AnimPattern, // special handling for "*.anim[1-9j]" pattern + OtherPattern + }; + PatternType detectPatternType(const QString &pattern) const; + QString m_pattern; QString m_mimeType; int m_weight; Qt::CaseSensitivity m_caseSensitivity; + PatternType m_patternType; }; Q_DECLARE_SHARED(QMimeGlobPattern) diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 12ce442f70..258dddf8cb 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -272,7 +272,6 @@ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile //qDebug() << pattern << mimeType << weight << caseSensitive; QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive); - // TODO: this could be done faster for literals where a simple == would do. if (glob.matchFileName(fileName)) result.addMatch(QLatin1String(mimeType), weight, pattern); } diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index a257cbc306..aad88da175 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -3139,7 +3139,10 @@ void QSignalEventGenerator::execute(void **_a) if (machinePrivate->state != QStateMachinePrivate::Running) return; int signalIndex = senderSignalIndex(); - Q_ASSERT(signalIndex != -1); + if (signalIndex == -1) { + qWarning() << "StateMachine: Could not execute transition because originating object has been deleted"; + return; + } machinePrivate->handleTransitionSignal(sender(), signalIndex, _a); } diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index d7e3cc5ee2..1f10150435 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -52,6 +52,10 @@ #include <QtCore/qatomic.h> #include <QtCore/qdatastream.h> +#if defined(Q_OS_MACOS) +#include <QtCore/private/qcore_mac_p.h> +#endif + #define PCRE2_CODE_UNIT_WIDTH 16 #include <pcre2.h> @@ -1122,6 +1126,8 @@ static bool isJitEnabled() #ifdef QT_DEBUG return false; +#elif defined(Q_OS_MACOS) + return !qt_mac_runningUnderRosetta(); #else return true; #endif @@ -1291,7 +1297,7 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString pcre2_jit_stack_assign_16(matchContext, &qtPcreCallback, nullptr); pcre2_match_data_16 *matchData = pcre2_match_data_create_from_pattern_16(compiledPattern, nullptr); - const unsigned short * const subjectUtf16 = subject.utf16() + subjectStart; + const auto subjectUtf16 = reinterpret_cast<const ushort*>(subject.data()) + subjectStart; int result; diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 8abb57586b..618b31e391 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -881,7 +881,7 @@ Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2) template <class T> Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr, uint seed = 0) { - return QT_PREPEND_NAMESPACE(qHash)(ptr.data(), seed); + return qHash(ptr.data(), seed); } diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 0110956b77..d8c229dea8 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -152,19 +152,18 @@ public: if (s == a) { // i.e. s != 0 T copy(t); realloc(s, s<<1); - const int idx = s++; - new (ptr + idx) T(std::move(copy)); + new (end()) T(std::move(copy)); } else { - const int idx = s++; - new (ptr + idx) T(t); + new (end()) T(t); } + ++s; } void append(T &&t) { if (s == a) realloc(s, s << 1); - const int idx = s++; - new (ptr + idx) T(std::move(t)); + new (end()) T(std::move(t)); + ++s; } void append(const T *buf, int size); @@ -501,7 +500,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA } template <class T, int Prealloc> -Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, size_type n, const T &t) +Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, int n, const T &t) { Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid"); @@ -538,6 +537,12 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA int f = int(abegin - ptr); int l = int(aend - ptr); int n = l - f; + + if (n == 0) // avoid UB in std::copy() below + return data() + f; + + Q_ASSERT(n > 0); // aend must be reachable from abegin + if (QTypeInfo<T>::isComplex) { std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f)); T *i = ptr + s; diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 6acbf3561e..85393a3598 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -835,18 +835,25 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c if (!isDetached() || d->size + n > int(d->alloc)) realloc(d->size + n, QArrayData::Grow); if (!QTypeInfoQuery<T>::isRelocatable) { - T *b = d->end(); - T *i = d->end() + n; - while (i != b) - new (--i) T; - i = d->end(); + T *const e = d->end(); + T *const b = d->begin() + offset; + + T *i = e; T *j = i + n; - b = d->begin() + offset; - while (i != b) - *--j = *--i; - i = b+n; + + // move old elements into the uninitialized space + while (i != b && j > e) + new (--j) T(std::move(*--i)); + // move the rest of old elements into the tail using assignment while (i != b) - *--i = copy; + *--j = std::move(*--i); + + // construct copies of t inside the uninitialized space + while (j != b && j > e) + new (--j) T(copy); + // use assignment to fill the recently-moved-from space + while (j != b) + *--j = copy; } else { T *b = d->begin() + offset; T *i = b + n; |