summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorTarja Sundqvist <[email protected]>2025-06-03 13:43:30 +0300
committerTarja Sundqvist <[email protected]>2025-06-03 13:43:30 +0300
commit4a6a9dcc73b82cd49a846d5eadadc1835d7b0ec8 (patch)
tree2f027d908308b8ad503b746cd9012fbc98ea32f2 /src/corelib
parent3fe9e69e4d7510480544f928e8a07f0f110b2181 (diff)
parent5d8e9a8415562ba004b38508d91e1fa0254c17d3 (diff)
Merge tag 'v6.5.6-lts-lgpl' into 6.56.5
Qt 6.5.6-lts-lgpl release
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/CMakeLists.txt7
-rw-r--r--src/corelib/Qt6AndroidMacros.cmake11
-rw-r--r--src/corelib/Qt6CoreDeploySupport.cmake7
-rw-r--r--src/corelib/Qt6CoreMacros.cmake25
-rw-r--r--src/corelib/compat/removed_api.cpp2
-rw-r--r--src/corelib/debug_script.py2
-rw-r--r--src/corelib/global/qcompilerdetection.h5
-rw-r--r--src/corelib/global/qglobalstatic.h8
-rw-r--r--src/corelib/global/qlibraryinfo.cpp15
-rw-r--r--src/corelib/global/qlibraryinfo_p.h2
-rw-r--r--src/corelib/global/qtypeinfo.h1
-rw-r--r--src/corelib/io/qdebug.h24
-rw-r--r--src/corelib/io/qloggingregistry.cpp6
-rw-r--r--src/corelib/io/qloggingregistry_p.h8
-rw-r--r--src/corelib/io/qsettings.cpp7
-rw-r--r--src/corelib/kernel/qeventdispatcher_wasm_p.h4
-rw-r--r--src/corelib/kernel/qmetaobject.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp44
-rw-r--r--src/corelib/kernel/qobject_p_p.h13
-rw-r--r--src/corelib/kernel/qproperty.cpp7
-rw-r--r--src/corelib/kernel/qproperty_p.h18
-rw-r--r--src/corelib/mimetypes/mime/hexdump.ps12
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp1
-rw-r--r--src/corelib/mimetypes/qmimemagicrule.cpp1
-rw-r--r--src/corelib/serialization/qcbormap.h2
-rw-r--r--src/corelib/serialization/qdatastream.cpp7
-rw-r--r--src/corelib/serialization/qxmlstream.cpp46
-rw-r--r--src/corelib/text/qbytearray.cpp3
-rw-r--r--src/corelib/text/qlocale.cpp14
-rw-r--r--src/corelib/text/qlocale.qdoc2
-rw-r--r--src/corelib/text/qlocale_mac.mm2
-rw-r--r--src/corelib/text/qlocale_p.h3
-rw-r--r--src/corelib/text/qlocale_unix.cpp7
-rw-r--r--src/corelib/text/qlocale_win.cpp2
-rw-r--r--src/corelib/text/qstringconverter.cpp8
-rw-r--r--src/corelib/text/qstringconverter_p.h9
-rw-r--r--src/corelib/text/qstringtokenizer.h1
-rw-r--r--src/corelib/text/qt_attribution.json4
-rw-r--r--src/corelib/thread/qfutureinterface.h2
-rw-r--r--src/corelib/time/qtimezoneprivate_tz.cpp31
-rw-r--r--src/corelib/tools/qcontainertools_impl.h9
-rw-r--r--src/corelib/tools/qlist.h6
-rw-r--r--src/corelib/tools/quniquehandle_p.h2
43 files changed, 262 insertions, 120 deletions
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index 4630a3a587f..4784a310f79 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -316,7 +316,6 @@ qt_internal_add_module(Core
text/qstringconverter.cpp # enum Data
tools/qcryptographichash.cpp # KeccakNISTInterface/Final
io/qdebug.cpp # undef qDebug
- io/qsettings.cpp # Space (also in qjsonparser.cpp)
NO_PCH_SOURCES
compat/removed_api.cpp
global/qsimd.cpp
@@ -1409,4 +1408,10 @@ foreach(minor_version RANGE ${PROJECT_VERSION_MINOR})
endforeach()
qt_internal_extend_target(Core
EXTRA_LINKER_SCRIPT_CONTENT "${linker_script_contents}"
+
+ # Workaround for QTBUG-117514:
+ # Function called by inline methods taking a pointer to a private class as a parameter
+ EXTRA_LINKER_SCRIPT_EXPORTS
+ # QFutureInterfaceBase::setContinuation(std::function<void (QFutureInterfaceBase const&)>, QFutureInterfaceBasePrivate*)
+ "_ZN20QFutureInterfaceBase15setContinuationE*P27QFutureInterfaceBasePrivate"
)
diff --git a/src/corelib/Qt6AndroidMacros.cmake b/src/corelib/Qt6AndroidMacros.cmake
index 9a8d02165f2..66f508f3b23 100644
--- a/src/corelib/Qt6AndroidMacros.cmake
+++ b/src/corelib/Qt6AndroidMacros.cmake
@@ -236,6 +236,10 @@ function(qt6_android_generate_deployment_settings target)
_qt_internal_add_android_deployment_property(file_contents "android-no-deploy-qt-libs"
${target} "QT_ANDROID_NO_DEPLOY_QT_LIBS")
+ __qt_internal_collect_plugin_targets_from_dependencies("${target}" plugin_targets)
+ __qt_internal_collect_plugin_library_files("${target}" "${plugin_targets}" plugin_targets)
+ string(APPEND file_contents " \"android-deploy-plugins\":\"${plugin_targets}\",\n")
+
# App binary
string(APPEND file_contents
" \"application-binary\": \"${target_output_name}\",\n")
@@ -303,7 +307,7 @@ function(qt6_android_generate_deployment_settings target)
# content end
string(APPEND file_contents "}\n")
- file(GENERATE OUTPUT ${deploy_file} CONTENT ${file_contents})
+ file(GENERATE OUTPUT ${deploy_file} CONTENT "${file_contents}")
set_target_properties(${target}
PROPERTIES
@@ -554,7 +558,7 @@ function(qt6_android_add_apk_target target)
"$<TARGET_FILE:${target}>"
"${androiddeployqt_output_path}/${target_file_copy_relative_path}"
)
- if(has_depfile_support)
+ if(has_depfile_support AND FALSE) # TODO: It breaks multi-abi builds. See QTBUG-122838
set(deploy_android_deps_dir "${apk_final_dir}/${target}_deploy_android")
set(timestamp_file "${deploy_android_deps_dir}/timestamp")
set(dep_file "${deploy_android_deps_dir}/${target}.d")
@@ -1007,7 +1011,8 @@ function(_qt_internal_get_android_abi_cmake_dir_path out_path abi)
NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_INTERNAL_IS_STANDALONE_TEST)
set(cmake_dir "${QT_CONFIG_BUILD_DIR}")
else()
- set(cmake_dir "${prefix_path}/${QT6_INSTALL_LIBS}/cmake")
+ string(TOUPPER "${QT_CMAKE_EXPORT_NAMESPACE}" export_namespace_upper)
+ set(cmake_dir "${prefix_path}/${${export_namespace_upper}_INSTALL_LIBS}/cmake")
endif()
endif()
diff --git a/src/corelib/Qt6CoreDeploySupport.cmake b/src/corelib/Qt6CoreDeploySupport.cmake
index 999708185ec..b3cfe29160f 100644
--- a/src/corelib/Qt6CoreDeploySupport.cmake
+++ b/src/corelib/Qt6CoreDeploySupport.cmake
@@ -437,8 +437,13 @@ function(qt6_deploy_runtime_dependencies)
# Specify path to target Qt's qtpaths .exe or .bat file, so windeployqt deploys the correct
# libraries when cross-compiling from x86_64 to arm64 windows.
- if(__QT_DEPLOY_TARGET_QT_PATHS_PATH)
+ if(__QT_DEPLOY_TARGET_QT_PATHS_PATH AND EXISTS "${__QT_DEPLOY_TARGET_QT_PATHS_PATH}")
list(APPEND tool_options --qtpaths "${__QT_DEPLOY_TARGET_QT_PATHS_PATH}")
+ else()
+ message(WARNING
+ "No qtpaths executable found for target Qt "
+ "at: ${__QT_DEPLOY_TARGET_QT_PATHS_PATH}. "
+ "Libraries may not be deployed correctly.")
endif()
elseif(__QT_DEPLOY_SYSTEM_NAME STREQUAL Darwin)
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index c692839b36f..f7f658d5afe 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -2666,7 +2666,30 @@ function(_qt_internal_setup_deploy_support)
else()
set(qt_paths_ext "")
endif()
- set(target_qtpaths_path "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_BINS}/qtpaths${qt_paths_ext}")
+
+
+
+ set(target_qtpaths_path "")
+ set(qtpaths_prefix "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_BINS}")
+ get_property(qt_major_version TARGET "${target}" PROPERTY INTERFACE_QT_MAJOR_VERSION)
+ if(qt_major_version)
+ set(target_qtpaths_with_major_version_path
+ "${qtpaths_prefix}/qtpaths${qt_major_version}${qt_paths_ext}")
+ if(EXISTS "${target_qtpaths_with_major_version_path}")
+ set(target_qtpaths_path "${target_qtpaths_with_major_version_path}")
+ endif()
+ endif()
+
+ if(NOT target_qtpaths_path)
+ set(target_qtpaths_path_without_version "${qtpaths_prefix}/qtpaths${qt_paths_ext}")
+ if(EXISTS "${target_qtpaths_path_without_version}")
+ set(target_qtpaths_path "${target_qtpaths_path_without_version}")
+ endif()
+ endif()
+
+ if(NOT target_qtpaths_path)
+ message(DEBUG "No qtpaths executable found for deployment purposes.")
+ endif()
file(GENERATE OUTPUT "${QT_DEPLOY_SUPPORT}" CONTENT
"cmake_minimum_required(VERSION 3.16...3.21)
diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp
index 7acbae8a5e8..586d84d9497 100644
--- a/src/corelib/compat/removed_api.cpp
+++ b/src/corelib/compat/removed_api.cpp
@@ -200,7 +200,7 @@ void QObject::setObjectName(const QString &name)
void QSettings::beginGroup(const QString &prefix)
{
- return beginGroup(qToAnyStringViewIgnoringNull(prefix));
+ beginGroup(qToAnyStringViewIgnoringNull(prefix));
}
int QSettings::beginReadArray(const QString &prefix)
diff --git a/src/corelib/debug_script.py b/src/corelib/debug_script.py
index 6dee5961524..f6207c6104e 100644
--- a/src/corelib/debug_script.py
+++ b/src/corelib/debug_script.py
@@ -1,5 +1,5 @@
# Copyright (C) 2017 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import os
import sys
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 58a36893412..02b5e64a69a 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -1370,6 +1370,11 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic
# endif
#endif
+// libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346
+#if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11)
+# define QT_COMPILER_HAS_LWG3346
+#endif
+
#endif // __cplusplus
#endif // QCOMPILERDETECTION_H
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index 26e22caced9..20701e0e54c 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -41,8 +41,16 @@ template <typename QGS> union Holder
~Holder()
{
+ // TSAN does not support atomic_thread_fence and GCC complains:
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97868
+ // https://github.com/google/sanitizers/issues/1352
+QT_WARNING_PUSH
+#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1100
+QT_WARNING_DISABLE_GCC("-Wtsan")
+#endif
// import changes to *pointer() by other threads before running ~PlainType():
std::atomic_thread_fence(std::memory_order_acquire);
+QT_WARNING_POP
pointer()->~PlainType();
guard.storeRelease(QtGlobalStatic::Destroyed);
}
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index ea281931c12..82857718911 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -87,10 +87,19 @@ void QLibrarySettings::load()
}
}
+namespace {
+const QString *qtconfManualPath = nullptr;
+}
+
+void QLibraryInfoPrivate::setQtconfManualPath(const QString *path)
+{
+ qtconfManualPath = path;
+}
+
static QSettings *findConfiguration()
{
- if (QLibraryInfoPrivate::qtconfManualPath)
- return new QSettings(*QLibraryInfoPrivate::qtconfManualPath, QSettings::IniFormat);
+ if (qtconfManualPath)
+ return new QSettings(*qtconfManualPath, QSettings::IniFormat);
QString qtconfig = QStringLiteral(":/qt/etc/qt.conf");
if (QFile::exists(qtconfig))
@@ -122,8 +131,6 @@ static QSettings *findConfiguration()
return nullptr; //no luck
}
-const QString *QLibraryInfoPrivate::qtconfManualPath = nullptr;
-
QSettings *QLibraryInfoPrivate::configuration()
{
QLibrarySettings *ls = qt_library_settings();
diff --git a/src/corelib/global/qlibraryinfo_p.h b/src/corelib/global/qlibraryinfo_p.h
index d3c458290b1..4b471b932e5 100644
--- a/src/corelib/global/qlibraryinfo_p.h
+++ b/src/corelib/global/qlibraryinfo_p.h
@@ -32,7 +32,7 @@ public:
#if QT_CONFIG(settings)
static QSettings *configuration();
static void reload();
- static const QString *qtconfManualPath;
+ static void setQtconfManualPath(const QString *qtconfManualPath);
#endif
struct LocationInfo
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index f493dce1ea4..95aa9f5dcdd 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -7,6 +7,7 @@
#include <variant>
#include <optional>
#include <tuple>
+#include <type_traits>
#ifndef QTYPEINFO_H
#define QTYPEINFO_H
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 7acb2ff027c..e925f37fb15 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -283,67 +283,67 @@ using QDebugIfHasDebugStreamContainer =
template<typename T>
inline QDebugIfHasDebugStreamContainer<QList<T>, T> operator<<(QDebug debug, const QList<T> &vec)
{
- return QtPrivate::printSequentialContainer(debug, "QList", vec);
+ return QtPrivate::printSequentialContainer(std::move(debug), "QList", vec);
}
template<typename T, qsizetype P>
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QVarLengthArray<T, P> &vec)
{
- return QtPrivate::printSequentialContainer(debug, "QVarLengthArray", vec);
+ return QtPrivate::printSequentialContainer(std::move(debug), "QVarLengthArray", vec);
}
template <typename T, typename Alloc>
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::vector<T, Alloc> &vec)
{
- return QtPrivate::printSequentialContainer(debug, "std::vector", vec);
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::vector", vec);
}
template <typename T, typename Alloc>
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::list<T, Alloc> &vec)
{
- return QtPrivate::printSequentialContainer(debug, "std::list", vec);
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::list", vec);
}
template <typename T>
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, std::initializer_list<T> list)
{
- return QtPrivate::printSequentialContainer(debug, "std::initializer_list", list);
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::initializer_list", list);
}
template <typename Key, typename T, typename Compare, typename Alloc>
inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map)
{
- return QtPrivate::printSequentialContainer(debug, "std::map", map); // yes, sequential: *it is std::pair
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::map", map); // yes, sequential: *it is std::pair
}
template <typename Key, typename T, typename Compare, typename Alloc>
inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map)
{
- return QtPrivate::printSequentialContainer(debug, "std::multimap", map); // yes, sequential: *it is std::pair
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::multimap", map); // yes, sequential: *it is std::pair
}
template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QMap<Key, T>, Key, T> operator<<(QDebug debug, const QMap<Key, T> &map)
{
- return QtPrivate::printAssociativeContainer(debug, "QMap", map);
+ return QtPrivate::printAssociativeContainer(std::move(debug), "QMap", map);
}
template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QMultiMap<Key, T>, Key, T> operator<<(QDebug debug, const QMultiMap<Key, T> &map)
{
- return QtPrivate::printAssociativeContainer(debug, "QMultiMap", map);
+ return QtPrivate::printAssociativeContainer(std::move(debug), "QMultiMap", map);
}
template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QHash<Key, T>, Key, T> operator<<(QDebug debug, const QHash<Key, T> &hash)
{
- return QtPrivate::printAssociativeContainer(debug, "QHash", hash);
+ return QtPrivate::printAssociativeContainer(std::move(debug), "QHash", hash);
}
template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QMultiHash<Key, T>, Key, T> operator<<(QDebug debug, const QMultiHash<Key, T> &hash)
{
- return QtPrivate::printAssociativeContainer(debug, "QMultiHash", hash);
+ return QtPrivate::printAssociativeContainer(std::move(debug), "QMultiHash", hash);
}
template <class T1, class T2>
@@ -357,7 +357,7 @@ inline QDebugIfHasDebugStream<T1, T2> operator<<(QDebug debug, const std::pair<T
template <typename T>
inline QDebugIfHasDebugStreamContainer<QSet<T>, T> operator<<(QDebug debug, const QSet<T> &set)
{
- return QtPrivate::printSequentialContainer(debug, "QSet", set);
+ return QtPrivate::printSequentialContainer(std::move(debug), "QSet", set);
}
template <class T>
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 98057222138..3d8c85dceeb 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -347,8 +347,8 @@ void QLoggingRegistry::unregisterCategory(QLoggingCategory *cat)
for enabling debugging by default for category \a categoryName. The
category name must start with "qt."
*/
-void QLoggingRegistry::registerEnvironmentOverrideForCategory(QByteArrayView categoryName,
- QByteArrayView environment)
+void QLoggingRegistry::registerEnvironmentOverrideForCategory(const char *categoryName,
+ const char *environment)
{
qtCategoryEnvironmentOverrides.insert(categoryName, environment);
}
@@ -442,7 +442,7 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
if (it == reg->qtCategoryEnvironmentOverrides.end())
debug = false;
else
- debug = qEnvironmentVariableIntValue(it.value().data());
+ debug = qEnvironmentVariableIntValue(it.value());
}
}
diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h
index 69ed1a4f96e..aa38ed895be 100644
--- a/src/corelib/io/qloggingregistry_p.h
+++ b/src/corelib/io/qloggingregistry_p.h
@@ -97,7 +97,7 @@ public:
#ifndef QT_BUILD_INTERNAL
Q_CORE_EXPORT // always export from QtCore
#endif
- void registerEnvironmentOverrideForCategory(QByteArrayView categoryName, QByteArrayView environment);
+ void registerEnvironmentOverrideForCategory(const char *categoryName, const char *environment);
void setApiRules(const QString &content);
@@ -127,7 +127,7 @@ private:
QList<QLoggingRule> ruleSets[NumRuleSets];
QHash<QLoggingCategory *, QtMsgType> categories;
QLoggingCategory::CategoryFilter categoryFilter;
- QMap<QByteArrayView, QByteArrayView> qtCategoryEnvironmentOverrides;
+ QMap<QByteArrayView, const char *> qtCategoryEnvironmentOverrides;
friend class ::tst_QLoggingRegistry;
};
@@ -140,12 +140,12 @@ public:
{}
private:
- static const char *registerOverride(QByteArrayView categoryName, QByteArrayView environment)
+ static const char *registerOverride(const char *categoryName, const char *environment)
{
QLoggingRegistry *c = QLoggingRegistry::instance();
if (c)
c->registerEnvironmentOverrideForCategory(categoryName, environment);
- return categoryName.data();
+ return categoryName;
}
};
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 41266d8219f..3c74fcb634d 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1494,6 +1494,8 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
}
}
+namespace SettingsImpl {
+
enum { Space = 0x1, Special = 0x2 };
static const char charTraits[256] =
@@ -1520,10 +1522,15 @@ static const char charTraits[256] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
+} // namespace SettingsImpl
+
+using SettingsImpl::charTraits;
+
bool QConfFileSettingsPrivate::readIniLine(QByteArrayView data, qsizetype &dataPos,
qsizetype &lineStart, qsizetype &lineLen,
qsizetype &equalsPos)
{
+ using namespace SettingsImpl;
qsizetype dataLen = data.size();
bool inQuotes = false;
diff --git a/src/corelib/kernel/qeventdispatcher_wasm_p.h b/src/corelib/kernel/qeventdispatcher_wasm_p.h
index 9ae92c811be..b2057af6cb7 100644
--- a/src/corelib/kernel/qeventdispatcher_wasm_p.h
+++ b/src/corelib/kernel/qeventdispatcher_wasm_p.h
@@ -50,7 +50,7 @@ public:
void interrupt() override;
void wakeUp() override;
- static void runOnMainThreadAsync(std::function<void(void)> fn);
+ static void runOnMainThread(std::function<void(void)> fn);
static void socketSelect(int timeout, int socket, bool waitForRead, bool waitForWrite,
bool *selectForRead, bool *selectForWrite, bool *socketDisconnect);
protected:
@@ -87,7 +87,7 @@ private:
static void run(std::function<void(void)> fn);
static void runAsync(std::function<void(void)> fn);
- static void runOnMainThread(std::function<void(void)> fn);
+ static void runOnMainThreadAsync(std::function<void(void)> fn);
static QEventDispatcherWasm *g_mainThreadEventDispatcher;
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 9c7c70a6c88..792fe986563 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -2338,7 +2338,7 @@ QMetaMethod::MethodType QMetaMethod::methodType() const
\since 5.0
Returns the meta-method that corresponds to the given \a signal, or an
- invalid QMetaMethod if \a signal is not a signal of the class.
+ invalid QMetaMethod if \a signal is \c{nullptr} or not a signal of the class.
Example:
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 65390d83fc8..a2e9b23ac6c 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -252,7 +252,7 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const
{
QObjectList returnValue;
int signal_index = signalIndex(signal);
- ConnectionData *cd = connections.loadRelaxed();
+ ConnectionData *cd = connections.loadAcquire();
if (signal_index < 0 || !cd)
return returnValue;
if (signal_index < cd->signalVectorCount()) {
@@ -281,13 +281,17 @@ QObjectList QObjectPrivate::senderList() const
return returnValue;
}
+/*!
+ \internal
+ The signalSlotLock() of the sender must be locked while calling this function
+*/
inline void QObjectPrivate::ensureConnectionData()
{
if (connections.loadRelaxed())
return;
ConnectionData *cd = new ConnectionData;
cd->ref.ref();
- connections.storeRelaxed(cd);
+ connections.storeRelease(cd);
}
/*!
@@ -452,7 +456,7 @@ bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative)
if (checkDeclarative && isDeclarativeSignalConnected(signalIndex))
return true;
- ConnectionData *cd = connections.loadRelaxed();
+ ConnectionData *cd = connections.loadAcquire();
if (!cd)
return false;
SignalVector *signalVector = cd->signalVector.loadRelaxed();
@@ -475,7 +479,7 @@ bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative)
bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const
{
- ConnectionData *cd = connections.loadRelaxed();
+ ConnectionData *cd = connections.loadAcquire();
if (!cd)
return false;
SignalVector *signalVector = cd->signalVector.loadRelaxed();
@@ -1015,8 +1019,8 @@ void QObjectPrivate::clearBindingStorage()
outside the parent. If you still do, the destroyed() signal gives
you an opportunity to detect when an object is destroyed.
- \warning Deleting a QObject while pending events are waiting to
- be delivered can cause a crash. You must not delete the QObject
+ \warning Deleting a QObject while it is handling an event
+ delivered to it can cause a crash. You must not delete the QObject
directly if it exists in a different thread than the one currently
executing. Use deleteLater() instead, which will cause the event
loop to delete the object after all pending events have been
@@ -1065,7 +1069,7 @@ QObject::~QObject()
if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::destroyed)
QAbstractDeclarativeData::destroyed(d->declarativeData, this);
- QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
+ QObjectPrivate::ConnectionData *cd = d->connections.loadAcquire();
if (cd) {
if (cd->currentSender) {
cd->currentSender->receiverDeleted();
@@ -1429,11 +1433,13 @@ bool QObject::event(QEvent *e)
{
QAbstractMetaCallEvent *mce = static_cast<QAbstractMetaCallEvent*>(e);
- if (!d_func()->connections.loadRelaxed()) {
+ QObjectPrivate::ConnectionData *connections = d_func()->connections.loadAcquire();
+ if (!connections) {
QMutexLocker locker(signalSlotLock(this));
d_func()->ensureConnectionData();
+ connections = d_func()->connections.loadRelaxed();
}
- QObjectPrivate::Sender sender(this, const_cast<QObject*>(mce->sender()), mce->signalId());
+ QObjectPrivate::Sender sender(this, const_cast<QObject*>(mce->sender()), mce->signalId(), connections);
mce->placeMetaCall(this);
break;
@@ -1766,7 +1772,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
}
// the current emitting thread shouldn't restore currentSender after calling moveToThread()
- ConnectionData *cd = connections.loadRelaxed();
+ ConnectionData *cd = connections.loadAcquire();
if (cd) {
if (cd->currentSender) {
cd->currentSender->receiverDeleted();
@@ -2709,8 +2715,8 @@ int QObject::receivers(const char *signal) const
signal_index);
}
- QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
QMutexLocker locker(signalSlotLock(this));
+ QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
if (cd && signal_index < cd->signalVectorCount()) {
const QObjectPrivate::Connection *c = cd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed();
while (c) {
@@ -3968,8 +3974,8 @@ void doActivate(QObject *sender, int signal_index, void **argv)
bool senderDeleted = false;
{
- Q_ASSERT(sp->connections.loadAcquire());
- QObjectPrivate::ConnectionDataPointer connections(sp->connections.loadRelaxed());
+ Q_ASSERT(sp->connections.loadRelaxed());
+ QObjectPrivate::ConnectionDataPointer connections(sp->connections.loadAcquire());
QObjectPrivate::SignalVector *signalVector = connections->signalVector.loadRelaxed();
const QObjectPrivate::ConnectionList *list;
@@ -4045,7 +4051,9 @@ void doActivate(QObject *sender, int signal_index, void **argv)
if (c->isSingleShot && !QObjectPrivate::removeConnection(c))
continue;
- QObjectPrivate::Sender senderData(receiverInSameThread ? receiver : nullptr, sender, signal_index);
+ QObjectPrivate::Sender senderData(
+ receiverInSameThread ? receiver : nullptr, sender, signal_index,
+ receiverInSameThread ? QObjectPrivate::get(receiver)->connections.loadAcquire() : nullptr);
if (c->isSlotObject) {
SlotObjectGuard obj{c->slotObj};
@@ -4094,7 +4102,7 @@ void doActivate(QObject *sender, int signal_index, void **argv)
senderDeleted = true;
}
if (!senderDeleted) {
- sp->connections.loadRelaxed()->cleanOrphanedConnections(sender);
+ sp->connections.loadAcquire()->cleanOrphanedConnections(sender);
if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
signal_spy_set->signal_end_callback(sender, signal_index);
@@ -5154,9 +5162,9 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
- if (type & Qt::UniqueConnection && slot && QObjectPrivate::get(s)->connections.loadRelaxed()) {
+ if (type & Qt::UniqueConnection && slot) {
QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(s)->connections.loadRelaxed();
- if (connections->signalVectorCount() > signal_index) {
+ if (connections && connections->signalVectorCount() > signal_index) {
const QObjectPrivate::Connection *c2 = connections->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed();
while (c2) {
@@ -5433,7 +5441,7 @@ inline bool QObjectPrivate::removeConnection(QObjectPrivate::Connection *c)
QtPrivate::QPropertyAdaptorSlotObject *
QObjectPrivate::getPropertyAdaptorSlotObject(const QMetaProperty &property)
{
- if (auto conns = connections.loadRelaxed()) {
+ if (auto conns = connections.loadAcquire()) {
Q_Q(QObject);
const QMetaObject *metaObject = q->metaObject();
int signal_index = methodIndexToSignalIndex(&metaObject, property.notifySignalIndex());
diff --git a/src/corelib/kernel/qobject_p_p.h b/src/corelib/kernel/qobject_p_p.h
index d79ce7e2b93..537ea55f4d7 100644
--- a/src/corelib/kernel/qobject_p_p.h
+++ b/src/corelib/kernel/qobject_p_p.h
@@ -215,19 +215,18 @@ struct QObjectPrivate::ConnectionData
struct QObjectPrivate::Sender
{
- Sender(QObject *receiver, QObject *sender, int signal)
+ Sender(QObject *receiver, QObject *sender, int signal, ConnectionData *receiverConnections)
: receiver(receiver), sender(sender), signal(signal)
{
- if (receiver) {
- ConnectionData *cd = receiver->d_func()->connections.loadRelaxed();
- previous = cd->currentSender;
- cd->currentSender = this;
+ if (receiverConnections) {
+ previous = receiverConnections->currentSender;
+ receiverConnections->currentSender = this;
}
}
~Sender()
{
if (receiver)
- receiver->d_func()->connections.loadRelaxed()->currentSender = previous;
+ receiver->d_func()->connections.loadAcquire()->currentSender = previous;
}
void receiverDeleted()
{
@@ -237,7 +236,7 @@ struct QObjectPrivate::Sender
s = s->previous;
}
}
- Sender *previous;
+ Sender *previous = nullptr;
QObject *receiver;
QObject *sender;
int signal;
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp
index 5e78489fdae..68f6f424104 100644
--- a/src/corelib/kernel/qproperty.cpp
+++ b/src/corelib/kernel/qproperty.cpp
@@ -732,13 +732,6 @@ void QPropertyObserverPointer::setChangeHandler(QPropertyObserver::ChangeHandler
ptr->next.setTag(QPropertyObserver::ObserverNotifiesChangeHandler);
}
-void QPropertyObserverPointer::setBindingToNotify(QPropertyBindingPrivate *binding)
-{
- Q_ASSERT(ptr->next.tag() != QPropertyObserver::ObserverIsPlaceholder);
- ptr->binding = binding;
- ptr->next.setTag(QPropertyObserver::ObserverNotifiesBinding);
-}
-
/*!
\internal
The same as as setBindingToNotify, but assumes that the tag is already correct.
diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h
index 77a744097eb..d8301e98852 100644
--- a/src/corelib/kernel/qproperty_p.h
+++ b/src/corelib/kernel/qproperty_p.h
@@ -134,7 +134,13 @@ struct QPropertyObserverPointer
unlink_common();
}
- void setBindingToNotify(QPropertyBindingPrivate *binding);
+ void setBindingToNotify(QPropertyBindingPrivate *binding)
+ {
+ Q_ASSERT(ptr->next.tag() != QPropertyObserver::ObserverIsPlaceholder);
+ ptr->binding = binding;
+ ptr->next.setTag(QPropertyObserver::ObserverNotifiesBinding);
+ }
+
void setBindingToNotify_unsafe(QPropertyBindingPrivate *binding);
void setChangeHandler(QPropertyObserver::ChangeHandler changeHandler);
@@ -937,7 +943,15 @@ QBindingObserverPtr::QBindingObserverPtr(QPropertyObserver *observer) noexcept :
QPropertyObserverPointer{d}.binding()->addRef();
}
-QBindingObserverPtr::~QBindingObserverPtr() { if (d) QPropertyObserverPointer{d}.binding()->deref(); }
+QBindingObserverPtr::~QBindingObserverPtr()
+{
+ if (!d)
+ return;
+
+ QPropertyBindingPrivate *bindingPrivate = binding();
+ if (!bindingPrivate->deref())
+ QPropertyBindingPrivate::destroyAndFreeMemory(bindingPrivate);
+}
QPropertyBindingPrivate *QBindingObserverPtr::binding() const noexcept { return QPropertyObserverPointer{d}.binding(); }
diff --git a/src/corelib/mimetypes/mime/hexdump.ps1 b/src/corelib/mimetypes/mime/hexdump.ps1
index 01d386fa821..26fb9dd6e65 100644
--- a/src/corelib/mimetypes/mime/hexdump.ps1
+++ b/src/corelib/mimetypes/mime/hexdump.ps1
@@ -1,5 +1,5 @@
# Copyright (C) 2019 Intel Corporation.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
param([String]$path, [String]$orig)
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index e196b778125..8aea2ff8455 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -12,7 +12,6 @@
#include <private/qfilesystementry_p.h>
-#include <QtCore/QMap>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QStandardPaths>
diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp
index 9111f1f0e9d..020e2d5a228 100644
--- a/src/corelib/mimetypes/qmimemagicrule.cpp
+++ b/src/corelib/mimetypes/qmimemagicrule.cpp
@@ -8,7 +8,6 @@
#include "qmimetypeparser_p.h"
#include <QtCore/QList>
-#include <QtCore/QMap>
#include <QtCore/QDebug>
#include <qendian.h>
diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h
index 523ef9ea349..e9918a30a56 100644
--- a/src/corelib/serialization/qcbormap.h
+++ b/src/corelib/serialization/qcbormap.h
@@ -40,6 +40,7 @@ public:
constexpr Iterator() = default;
constexpr Iterator(const Iterator &) = default;
+ ~Iterator() = default;
Iterator &operator=(const Iterator &other)
{
// rebind the reference
@@ -100,6 +101,7 @@ public:
constexpr ConstIterator() = default;
constexpr ConstIterator(const ConstIterator &) = default;
+ ~ConstIterator() = default;
ConstIterator &operator=(const ConstIterator &other)
{
// rebind the reference
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index b364f7f9e2f..cc7a3604cf6 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -1056,13 +1056,15 @@ QDataStream &QDataStream::readBytes(char *&s, uint &l)
if (len == 0)
return *this;
- const quint32 Step = 1024 * 1024;
+ quint32 step = 1024 * 1024;
quint32 allocated = 0;
char *prevBuf = nullptr;
char *curBuf = nullptr;
+ constexpr quint32 MaxBlockSize = std::numeric_limits<int>::max();
do {
- int blockSize = qMin(Step, len - allocated);
+ const quint32 sz = qMin(step, len - allocated);
+ int blockSize = qMin(sz, MaxBlockSize);
prevBuf = curBuf;
curBuf = new char[allocated + blockSize + 1];
if (prevBuf) {
@@ -1074,6 +1076,7 @@ QDataStream &QDataStream::readBytes(char *&s, uint &l)
return *this;
}
allocated += blockSize;
+ step *= 2;
} while (allocated < len);
s = curBuf;
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index 48839d832e6..21153603525 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -2981,54 +2981,80 @@ void QXmlStreamWriterPrivate::write(QAnyStringView s)
void QXmlStreamWriterPrivate::writeEscaped(QAnyStringView s, bool escapeWhitespace)
{
+ struct NextLatin1 {
+ char32_t operator()(const char *&it, const char *) const
+ { return uchar(*it++); }
+ };
+ struct NextUtf8 {
+ char32_t operator()(const char *&it, const char *end) const
+ {
+ uchar uc = *it++;
+ char32_t utf32 = 0;
+ char32_t *output = &utf32;
+ qsizetype n = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(uc, output, it, end);
+ return n < 0 ? 0 : utf32;
+ }
+ };
+ struct NextUtf16 {
+ char32_t operator()(const QChar *&it, const QChar *) const
+ {
+ return (it++)->unicode();
+ }
+ };
+
QString escaped;
escaped.reserve(s.size());
s.visit([&] (auto s) {
using View = decltype(s);
+ using Decoder = std::conditional_t<std::is_same_v<View, QLatin1StringView>, NextLatin1,
+ std::conditional_t<std::is_same_v<View, QUtf8StringView>, NextUtf8, NextUtf16>>;
auto it = s.begin();
const auto end = s.end();
+ Decoder decoder;
while (it != end) {
QLatin1StringView replacement;
auto mark = it;
while (it != end) {
- if (*it == u'<') {
+ auto next_it = it;
+ char32_t uc = decoder(next_it, end);
+ if (uc == u'<') {
replacement = "&lt;"_L1;
break;
- } else if (*it == u'>') {
+ } else if (uc == u'>') {
replacement = "&gt;"_L1;
break;
- } else if (*it == u'&') {
+ } else if (uc == u'&') {
replacement = "&amp;"_L1;
break;
- } else if (*it == u'\"') {
+ } else if (uc == u'\"') {
replacement = "&quot;"_L1;
break;
- } else if (*it == u'\t') {
+ } else if (uc == u'\t') {
if (escapeWhitespace) {
replacement = "&#9;"_L1;
break;
}
- } else if (*it == u'\n') {
+ } else if (uc == u'\n') {
if (escapeWhitespace) {
replacement = "&#10;"_L1;
break;
}
- } else if (*it == u'\v' || *it == u'\f') {
+ } else if (uc == u'\v' || uc == u'\f') {
hasEncodingError = true;
break;
- } else if (*it == u'\r') {
+ } else if (uc == u'\r') {
if (escapeWhitespace) {
replacement = "&#13;"_L1;
break;
}
- } else if (*it <= u'\x1F' || *it >= u'\uFFFE') {
+ } else if (uc <= u'\x1F' || uc == u'\uFFFE' || uc == u'\uFFFF') {
hasEncodingError = true;
break;
}
- ++it;
+ it = next_it;
}
escaped.append(View{mark, it});
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
index 8faa130d38f..e6399baf909 100644
--- a/src/corelib/text/qbytearray.cpp
+++ b/src/corelib/text/qbytearray.cpp
@@ -1342,6 +1342,9 @@ QByteArray &QByteArray::operator=(const QByteArray & other) noexcept
\overload
Assigns \a str to this byte array.
+
+ \a str is assumed to point to a null-terminated string, and its length is
+ determined dynamically.
*/
QByteArray &QByteArray::operator=(const char *str)
diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp
index 4466a460b23..1a2fbee2357 100644
--- a/src/corelib/text/qlocale.cpp
+++ b/src/corelib/text/qlocale.cpp
@@ -109,18 +109,18 @@ QLocale::Language QLocalePrivate::codeToLanguage(QStringView code,
auto searchCode = [codeBuf](auto f) {
return std::find_if(languageCodeList.begin(), languageCodeList.end(),
- [=](const LanguageCodeEntry &i) { return f(i) == codeBuf; });
+ [=](LanguageCodeEntry i) { return f(i) == codeBuf; });
};
if (codeTypes.testFlag(QLocale::ISO639Part1) && uc3 == 0) {
- auto i = searchCode([](const LanguageCodeEntry &i) { return i.part1; });
+ auto i = searchCode([](LanguageCodeEntry i) { return i.part1; });
if (i != languageCodeList.end())
return QLocale::Language(std::distance(languageCodeList.begin(), i));
}
if (uc3 != 0) {
if (codeTypes.testFlag(QLocale::ISO639Part2B)) {
- auto i = searchCode([](const LanguageCodeEntry &i) { return i.part2B; });
+ auto i = searchCode([](LanguageCodeEntry i) { return i.part2B; });
if (i != languageCodeList.end())
return QLocale::Language(std::distance(languageCodeList.begin(), i));
}
@@ -129,13 +129,13 @@ QLocale::Language QLocalePrivate::codeToLanguage(QStringView code,
// This is asserted in iso639_3.LanguageCodeData.
if (codeTypes.testFlag(QLocale::ISO639Part2T)
&& !codeTypes.testFlag(QLocale::ISO639Part3)) {
- auto i = searchCode([](const LanguageCodeEntry &i) { return i.part2T; });
+ auto i = searchCode([](LanguageCodeEntry i) { return i.part2T; });
if (i != languageCodeList.end())
return QLocale::Language(std::distance(languageCodeList.begin(), i));
}
if (codeTypes.testFlag(QLocale::ISO639Part3)) {
- auto i = searchCode([](const LanguageCodeEntry &i) { return i.part3; });
+ auto i = searchCode([](LanguageCodeEntry i) { return i.part3; });
if (i != languageCodeList.end())
return QLocale::Language(std::distance(languageCodeList.begin(), i));
}
@@ -250,7 +250,7 @@ struct LikelyPair
QLocaleId value = QLocaleId { 0, 0, 0 };
};
-bool operator<(const LikelyPair &lhs, const LikelyPair &rhs)
+bool operator<(LikelyPair lhs, LikelyPair rhs)
{
// Must match the comparison LocaleDataWriter.likelySubtags() uses when
// sorting, see qtbase/util/locale_database.qlocalexml2cpp.py
@@ -461,7 +461,7 @@ QByteArray QLocalePrivate::bcp47Name(char separator) const
return m_data->id().withLikelySubtagsRemoved().name(separator);
}
-static qsizetype findLocaleIndexById(const QLocaleId &localeId)
+static qsizetype findLocaleIndexById(QLocaleId localeId)
{
qsizetype idx = locale_index[localeId.language_id];
// If there are no locales for specified language (so we we've got the
diff --git a/src/corelib/text/qlocale.qdoc b/src/corelib/text/qlocale.qdoc
index fcc4ab4cfb1..f81c10a87fe 100644
--- a/src/corelib/text/qlocale.qdoc
+++ b/src/corelib/text/qlocale.qdoc
@@ -1153,7 +1153,7 @@
*/
/*!
- \fn QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
+ \fn QVariant QSystemLocale::query(QueryType type, QVariant &&in = QVariant()) const
Generic query method for locale data. Provides indirection.
Denotes the \a type of the query
diff --git a/src/corelib/text/qlocale_mac.mm b/src/corelib/text/qlocale_mac.mm
index ec592616c53..9c3f7a4f31c 100644
--- a/src/corelib/text/qlocale_mac.mm
+++ b/src/corelib/text/qlocale_mac.mm
@@ -571,7 +571,7 @@ static QLocale::Language codeToLanguage(QStringView s)
return QLocalePrivate::codeToLanguage(s);
}
-QVariant QSystemLocale::query(QueryType type, QVariant in) const
+QVariant QSystemLocale::query(QueryType type, QVariant &&in) const
{
QMacAutoReleasePool pool;
diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h
index cb1adfbe592..8a61dd77829 100644
--- a/src/corelib/text/qlocale_p.h
+++ b/src/corelib/text/qlocale_p.h
@@ -35,6 +35,7 @@ struct QLocaleData;
// Subclassed by Android platform plugin:
class Q_CORE_EXPORT QSystemLocale
{
+ Q_DISABLE_COPY_MOVE(QSystemLocale)
QSystemLocale *next = nullptr; // Maintains a stack.
public:
QSystemLocale();
@@ -98,7 +99,7 @@ public:
StandaloneDayNameShort, // QString, in: int
StandaloneDayNameNarrow // QString, in: int
};
- virtual QVariant query(QueryType type, QVariant in = QVariant()) const;
+ virtual QVariant query(QueryType type, QVariant &&in = QVariant()) const;
virtual QLocale fallbackLocale() const;
inline qsizetype fallbackLocaleIndex() const;
diff --git a/src/corelib/text/qlocale_unix.cpp b/src/corelib/text/qlocale_unix.cpp
index 6f6884d3661..a0c9ecc4341 100644
--- a/src/corelib/text/qlocale_unix.cpp
+++ b/src/corelib/text/qlocale_unix.cpp
@@ -124,7 +124,7 @@ QLocale QSystemLocale::fallbackLocale() const
return QLocale(lang);
}
-QVariant QSystemLocale::query(QueryType type, QVariant in) const
+QVariant QSystemLocale::query(QueryType type, QVariant &&in) const
{
QSystemLocaleData *d = qSystemLocaleData();
@@ -258,9 +258,10 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
return d->uiLanguages.isEmpty() ? QVariant() : QVariant(d->uiLanguages);
}
case StringToStandardQuotation:
- return lc_messages.quoteString(qvariant_cast<QStringView>(in));
+ return lc_messages.quoteString(qvariant_cast<QStringView>(std::move(in)));
case StringToAlternateQuotation:
- return lc_messages.quoteString(qvariant_cast<QStringView>(in), QLocale::AlternateQuotation);
+ return lc_messages.quoteString(qvariant_cast<QStringView>(std::move(in)),
+ QLocale::AlternateQuotation);
case ListToSeparatedString:
return lc_messages.createSeparatedList(in.toStringList());
case LocaleChanged:
diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp
index 3454e859852..9ce9f9af4b0 100644
--- a/src/corelib/text/qlocale_win.cpp
+++ b/src/corelib/text/qlocale_win.cpp
@@ -837,7 +837,7 @@ QLocale QSystemLocale::fallbackLocale() const
return QLocale(QString::fromLatin1(getWinLocaleName()));
}
-QVariant QSystemLocale::query(QueryType type, QVariant in) const
+QVariant QSystemLocale::query(QueryType type, QVariant &&in) const
{
QSystemLocalePrivate *d = systemLocalePrivate();
switch(type) {
diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp
index 8b67cbeabce..a3a0b3c4f8c 100644
--- a/src/corelib/text/qstringconverter.cpp
+++ b/src/corelib/text/qstringconverter.cpp
@@ -1365,10 +1365,10 @@ QString QLocal8Bit::convertToUnicode_sys(QByteArrayView in, quint32 codePage,
// encounter an error
int nextIn = qt_saturate<int>(mblen);
while (mblen > 0) {
- const int nextOut = qt_saturate<int>(outlen);
std::tie(out, outlen) = growOut(1); // Need space for at least one character
if (!out)
return {};
+ const int nextOut = qt_saturate<int>(outlen);
len = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, mb, nextIn, out, nextOut);
if (len) {
mb += nextIn;
@@ -1576,9 +1576,11 @@ QByteArray QLocal8Bit::convertFromUnicode_sys(QStringView in, quint32 codePage,
// incomplete sequence, probably a Windows bug. We try to avoid that from
// happening by reducing the window size in that case. But let's keep this
// branch just in case of other bugs.
+#ifndef QT_NO_DEBUG
r = GetLastError();
fprintf(stderr,
"WideCharToMultiByte: Cannot convert multibyte text (error %d)\n", r);
+#endif // !QT_NO_DEBUG
break;
}
std::tie(out, outlen) = growOut(neededLength);
@@ -1964,7 +1966,7 @@ struct QStringConverterICU : QStringConverter
const void *context;
ucnv_getToUCallBack(icu_conv, &action, &context);
if (context != state)
- ucnv_setToUCallBack(icu_conv, action, &state, nullptr, nullptr, &err);
+ ucnv_setToUCallBack(icu_conv, action, state, nullptr, nullptr, &err);
ucnv_toUnicode(icu_conv, &target, targetLimit, &source, sourceLimit, nullptr, flush, &err);
// We did reserve enough space:
@@ -1997,7 +1999,7 @@ struct QStringConverterICU : QStringConverter
const void *context;
ucnv_getFromUCallBack(icu_conv, &action, &context);
if (context != state)
- ucnv_setFromUCallBack(icu_conv, action, &state, nullptr, nullptr, &err);
+ ucnv_setFromUCallBack(icu_conv, action, state, nullptr, nullptr, &err);
ucnv_fromUnicode(icu_conv, &target, targetLimit, &source, sourceLimit, nullptr, flush, &err);
// We did reserve enough space:
diff --git a/src/corelib/text/qstringconverter_p.h b/src/corelib/text/qstringconverter_p.h
index 40f9b62a3ee..da19fa70577 100644
--- a/src/corelib/text/qstringconverter_p.h
+++ b/src/corelib/text/qstringconverter_p.h
@@ -43,18 +43,27 @@ struct QUtf8BaseTraits
static void appendByte(qchar8_t *&ptr, qchar8_t b)
{ *ptr++ = b; }
+ static uchar peekByte(const char *ptr, qsizetype n = 0)
+ { return ptr[n]; }
+
static uchar peekByte(const uchar *ptr, qsizetype n = 0)
{ return ptr[n]; }
static uchar peekByte(const qchar8_t *ptr, qsizetype n = 0)
{ return ptr[n]; }
+ static qptrdiff availableBytes(const char *ptr, const char *end)
+ { return end - ptr; }
+
static qptrdiff availableBytes(const uchar *ptr, const uchar *end)
{ return end - ptr; }
static qptrdiff availableBytes(const qchar8_t *ptr, const qchar8_t *end)
{ return end - ptr; }
+ static void advanceByte(const char *&ptr, qsizetype n = 1)
+ { ptr += n; }
+
static void advanceByte(const uchar *&ptr, qsizetype n = 1)
{ ptr += n; }
diff --git a/src/corelib/text/qstringtokenizer.h b/src/corelib/text/qstringtokenizer.h
index 2b679608f91..7a627b45084 100644
--- a/src/corelib/text/qstringtokenizer.h
+++ b/src/corelib/text/qstringtokenizer.h
@@ -5,6 +5,7 @@
#include <QtCore/qnamespace.h>
#include <QtCore/qcontainerfwd.h>
+#include <iterator>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/text/qt_attribution.json b/src/corelib/text/qt_attribution.json
index 0084ccc18d9..3ae1bd2925a 100644
--- a/src/corelib/text/qt_attribution.json
+++ b/src/corelib/text/qt_attribution.json
@@ -35,8 +35,8 @@
available.",
"Homepage": "https://cldr.unicode.org/",
"Version": "v44.1",
- "License": "Unicode License V3",
- "LicenseId": "UNICODE-3.0",
+ "License": "Unicode License v3",
+ "LicenseId": "Unicode-3.0",
"Copyright": "Copyright (C) 2004-2023 Unicode, Inc."
}
]
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index 7e682e69b68..86b8cbd3484 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -452,7 +452,7 @@ template <>
class QFutureInterface<void> : public QFutureInterfaceBase
{
public:
- explicit QFutureInterface<void>(State initialState = NoState)
+ explicit QFutureInterface(State initialState = NoState)
: QFutureInterfaceBase(initialState)
{ }
diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
index f1ea6128ae3..276291a4719 100644
--- a/src/corelib/time/qtimezoneprivate_tz.cpp
+++ b/src/corelib/time/qtimezoneprivate_tz.cpp
@@ -578,7 +578,12 @@ PosixZone PosixZone::parse(const char *&pos, const char *end)
return {std::move(name), offset};
}
-static auto validatePosixRule(const QByteArray &posixRule)
+/* Parse and check a POSIX rule.
+
+ By default a simple zone abbreviation with no offset information is accepted.
+ Set \a requireOffset to \c true to require that there be offset data present.
+*/
+static auto validatePosixRule(const QByteArray &posixRule, bool requireOffset = false)
{
// Format is described here:
// http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
@@ -590,15 +595,19 @@ static auto validatePosixRule(const QByteArray &posixRule)
return fail;
const char *begin = zoneinfo.begin();
-
- // Updates begin to point after the name and offset it parses:
- if (PosixZone::parse(begin, zoneinfo.end()).name.isEmpty())
- return fail;
+ {
+ // Updates begin to point after the name and offset it parses:
+ const auto posix = PosixZone::parse(begin, zoneinfo.end());
+ if (posix.name.isEmpty())
+ return fail;
+ if (requireOffset && !posix.hasValidOffset())
+ return fail;
+ }
if (good.hasDst) {
if (begin >= zoneinfo.end())
return fail;
- // Expect a second name and offset after the first:
+ // Expect a second name (and optional offset) after the first:
if (PosixZone::parse(begin, zoneinfo.end()).name.isEmpty())
return fail;
}
@@ -772,7 +781,7 @@ public:
QTzTimeZoneCacheEntry fetchEntry(const QByteArray &ianaId);
private:
- QTzTimeZoneCacheEntry findEntry(const QByteArray &ianaId);
+ static QTzTimeZoneCacheEntry findEntry(const QByteArray &ianaId);
QCache<QByteArray, QTzTimeZoneCacheEntry> m_cache;
QMutex m_mutex;
};
@@ -977,6 +986,8 @@ QTzTimeZoneCacheEntry QTzTimeZoneCache::fetchEntry(const QByteArray &ianaId)
// Create a named time zone
QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &ianaId)
{
+ if (!isTimeZoneIdAvailable(ianaId)) // Avoid pointlessly creating cache entries
+ return;
static QTzTimeZoneCache tzCache;
auto entry = tzCache.fetchEntry(ianaId);
if (entry.m_tranTimes.isEmpty() && entry.m_posixRule.isEmpty())
@@ -1239,7 +1250,11 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs
bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
{
- return tzZones->contains(ianaId);
+ // Allow a POSIX rule as long as it has offset data. (This needs to reject a
+ // plain abbreviation, without offset, since claiming to support such zones
+ // would prevent the custom QTimeZone constructor from accepting such a
+ // name, as it doesn't want a custom zone to over-ride a "real" one.)
+ return tzZones->contains(ianaId) || validatePosixRule(ianaId, true).isValid;
}
QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const
diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h
index d380421170c..7efea45acd2 100644
--- a/src/corelib/tools/qcontainertools_impl.h
+++ b/src/corelib/tools/qcontainertools_impl.h
@@ -265,7 +265,11 @@ using IfAssociativeIteratorHasKeyAndValue =
template <typename Iterator>
using IfAssociativeIteratorHasFirstAndSecond =
- std::enable_if_t<qxp::is_detected_v<FirstAndSecondTest, Iterator>, bool>;
+ std::enable_if_t<
+ std::conjunction_v<
+ std::negation<qxp::is_detected<KeyAndValueTest, Iterator>>,
+ qxp::is_detected<FirstAndSecondTest, Iterator>
+ >, bool>;
template <typename T, typename U>
using IfIsNotSame =
@@ -323,8 +327,7 @@ template <typename Container, typename T>
auto sequential_erase_with_copy(Container &c, const T &t)
{
using CopyProxy = std::conditional_t<std::is_copy_constructible_v<T>, T, const T &>;
- const T &tCopy = CopyProxy(t);
- return sequential_erase(c, tCopy);
+ return sequential_erase(c, CopyProxy(t));
}
template <typename Container, typename T>
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index d61b90503a4..8ed4110bae7 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -109,8 +109,7 @@ public:
public:
using difference_type = qsizetype;
using value_type = T;
- // libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346
-#if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11)
+#ifdef QT_COMPILER_HAS_LWG3346
using iterator_concept = std::contiguous_iterator_tag;
using element_type = value_type;
#endif
@@ -180,8 +179,7 @@ public:
public:
using difference_type = qsizetype;
using value_type = T;
- // libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346
-#if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11)
+#ifdef QT_COMPILER_HAS_LWG3346
using iterator_concept = std::contiguous_iterator_tag;
using element_type = const value_type;
#endif
diff --git a/src/corelib/tools/quniquehandle_p.h b/src/corelib/tools/quniquehandle_p.h
index e31699a1229..7af1536c2ed 100644
--- a/src/corelib/tools/quniquehandle_p.h
+++ b/src/corelib/tools/quniquehandle_p.h
@@ -1,5 +1,5 @@
// Copyright (C) 2023 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QUNIQUEHANDLE_P_H
#define QUNIQUEHANDLE_P_H