summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/Qt5AndroidSupport.cmake22
-rw-r--r--src/corelib/global/qcompilerdetection.h17
-rw-r--r--src/corelib/global/qendian_p.h193
-rw-r--r--src/corelib/global/qnamespace.qdoc16
-rw-r--r--src/corelib/global/qrandom.cpp1
-rw-r--r--src/corelib/io/qbuffer.cpp10
-rw-r--r--src/corelib/io/qsettings.cpp18
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp16
-rw-r--r--src/corelib/kernel/qcore_mac.mm25
-rw-r--r--src/corelib/kernel/qelapsedtimer.cpp27
-rw-r--r--src/corelib/kernel/qobject.cpp2
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h10
-rw-r--r--src/corelib/kernel/qsharedmemory_systemv.cpp2
-rw-r--r--src/corelib/kernel/qtimer.cpp2
-rw-r--r--src/corelib/serialization/qbinaryjson.cpp81
-rw-r--r--src/corelib/serialization/qbinaryjson_p.h102
-rw-r--r--src/corelib/serialization/qbinaryjsonarray.cpp12
-rw-r--r--src/corelib/serialization/qbinaryjsonobject.cpp14
-rw-r--r--src/corelib/serialization/qbinaryjsonvalue.cpp2
-rw-r--r--src/corelib/serialization/qxmlstream.cpp2
-rw-r--r--src/corelib/serialization/qxmlstream.g2
-rw-r--r--src/corelib/serialization/qxmlstream_p.h2
-rw-r--r--src/corelib/thread/qreadwritelock.cpp4
-rw-r--r--src/corelib/thread/qsemaphore.cpp9
-rw-r--r--src/corelib/time/qdatetime.cpp46
-rw-r--r--src/corelib/time/qdatetimeparser.cpp13
-rw-r--r--src/corelib/time/qtimezoneprivate_android.cpp15
-rw-r--r--src/corelib/tools/qsharedpointer.cpp4
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h6
29 files changed, 481 insertions, 194 deletions
diff --git a/src/corelib/Qt5AndroidSupport.cmake b/src/corelib/Qt5AndroidSupport.cmake
index 6aca9299bc..207539207d 100644
--- a/src/corelib/Qt5AndroidSupport.cmake
+++ b/src/corelib/Qt5AndroidSupport.cmake
@@ -1,3 +1,18 @@
+function(qt_internal_get_highest_android_sdk_build_tools_revision out_var build_tools_dir)
+ file(GLOB revisions RELATIVE "${build_tools_dir}" "${build_tools_dir}/*")
+ if(NOT revisions)
+ message(FATAL_ERROR "Cannot determine version of Android build tools. "
+ "Please specify ANDROID_SDK_BUILD_TOOLS_REVISION manually.")
+ endif()
+ set(highest_revision 1.0)
+ foreach(revision IN LISTS revisions)
+ if(revision VERSION_GREATER highest_revision)
+ set(highest_revision ${revision})
+ endif()
+ endforeach()
+ set(${out_var} ${highest_revision} PARENT_SCOPE)
+endfunction()
+
if (NOT ${PROJECT_NAME}-MultiAbiBuild)
set(ANDROID_ABIS armeabi-v7a arm64-v8a x86 x86_64)
@@ -37,6 +52,12 @@ if (NOT ${PROJECT_NAME}-MultiAbiBuild)
VERBATIM)
endif()
+ if("${ANDROID_SDK_BUILD_TOOLS_REVISION}" STREQUAL "")
+ qt_internal_get_highest_android_sdk_build_tools_revision(
+ ANDROID_SDK_BUILD_TOOLS_REVISION
+ "${ANDROID_SDK}/build-tools")
+ endif()
+
# Write the android_<project_name>_deployment_settings.json file
file(WRITE ${CMAKE_BINARY_DIR}/android_deployment_settings.json.in
[=[{
@@ -57,6 +78,7 @@ if (NOT ${PROJECT_NAME}-MultiAbiBuild)
"qml-root-path": "@CMAKE_CURRENT_SOURCE_DIR@",
"qt": "@QT_DIR@",
"sdk": "@ANDROID_SDK@",
+ "sdkBuildToolsRevision": "@ANDROID_SDK_BUILD_TOOLS_REVISION@",
"stdcpp-path": "@ANDROID_TOOLCHAIN_ROOT@/sysroot/usr/lib/",
"tool-prefix": "llvm",
"toolchain-prefix": "llvm",
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 03972594e7..d8a44655dd 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -83,11 +83,14 @@
# endif
#elif defined(_MSC_VER)
+# define Q_CC_MSVC (_MSC_VER)
+# define Q_CC_MSVC_NET
+# define Q_CC_MSVC_ONLY Q_CC_MSVC
# ifdef __clang__
+# undef Q_CC_MSVC_ONLY
# define Q_CC_CLANG ((__clang_major__ * 100) + __clang_minor__)
+# define Q_CC_CLANG_ONLY Q_CC_CLANG
# endif
-# define Q_CC_MSVC (_MSC_VER)
-# define Q_CC_MSVC_NET
# define Q_OUTOFLINE_TEMPLATE inline
# define Q_COMPILER_MANGLES_RETURN_TYPE
# define Q_FUNC_INFO __FUNCSIG__
@@ -106,6 +109,10 @@
# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N)) // Since _MSC_VER >= 1500
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
# if defined(__INTEL_COMPILER)
+# undef Q_CC_MSVC_ONLY
+# ifdef Q_CC_CLANG_ONLY
+# undef Q_CC_CLANG_ONLY
+# endif
# define Q_DECL_VARIABLE_DEPRECATED
# define Q_CC_INTEL __INTEL_COMPILER
# endif
@@ -183,6 +190,7 @@
# else
# define Q_CC_CLANG ((__clang_major__ * 100) + __clang_minor__)
# endif
+# define Q_CC_CLANG_ONLY Q_CC_CLANG
# if __has_builtin(__builtin_assume)
# define Q_ASSUME_IMPL(expr) __builtin_assume(expr)
# else
@@ -205,6 +213,7 @@
# endif
# else
/* Plain GCC */
+# define Q_CC_GNU_ONLY Q_CC_GNU
# if Q_CC_GNU >= 405
# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
@@ -836,7 +845,7 @@
# define Q_DECL_UNUSED_MEMBER Q_DECL_UNUSED
#endif
-#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
+#if defined(Q_CC_GNU_ONLY)
# define Q_COMPILER_RESTRICTED_VLA
# define Q_COMPILER_THREADSAFE_STATICS
# if Q_CC_GNU >= 403
diff --git a/src/corelib/global/qendian_p.h b/src/corelib/global/qendian_p.h
index c830e65b54..5421a452d9 100644
--- a/src/corelib/global/qendian_p.h
+++ b/src/corelib/global/qendian_p.h
@@ -52,6 +52,7 @@
//
#include <QtCore/qendian.h>
+#include <type_traits>
QT_BEGIN_NAMESPACE
@@ -136,6 +137,198 @@ using qint32_be_bitfield = QBEIntegerBitfield<int, pos, width>;
template<int pos, int width>
using quint32_be_bitfield = QBEIntegerBitfield<uint, pos, width>;
+enum class QSpecialIntegerBitfieldInitializer {};
+constexpr QSpecialIntegerBitfieldInitializer QSpecialIntegerBitfieldZero{};
+
+template<class S>
+class QSpecialIntegerStorage
+{
+public:
+ using UnsignedStorageType = typename std::make_unsigned<typename S::StorageType>::type;
+
+ constexpr QSpecialIntegerStorage() = default;
+ constexpr QSpecialIntegerStorage(QSpecialIntegerBitfieldInitializer) : val(0) {}
+ constexpr QSpecialIntegerStorage(UnsignedStorageType initial) : val(initial) {}
+
+ UnsignedStorageType val;
+};
+
+template<class S, int pos, int width, class T = typename S::StorageType>
+class QSpecialIntegerAccessor;
+
+template<class S, int pos, int width, class T = typename S::StorageType>
+class QSpecialIntegerConstAccessor
+{
+ Q_DISABLE_COPY(QSpecialIntegerConstAccessor)
+public:
+ using Storage = const QSpecialIntegerStorage<S>;
+ using Type = T;
+ using UnsignedType = typename std::make_unsigned<T>::type;
+
+ QSpecialIntegerConstAccessor(QSpecialIntegerConstAccessor &&) noexcept = default;
+ QSpecialIntegerConstAccessor &operator=(QSpecialIntegerConstAccessor &&) noexcept = default;
+
+ operator Type() const noexcept
+ {
+ if (std::is_signed<Type>::value) {
+ UnsignedType i = S::fromSpecial(storage->val);
+ i <<= (sizeof(Type) * 8) - width - pos;
+ Type t = Type(i);
+ t >>= (sizeof(Type) * 8) - width;
+ return t;
+ }
+ return (S::fromSpecial(storage->val) & mask()) >> pos;
+ }
+
+ bool operator!() const noexcept { return !(storage->val & S::toSpecial(mask())); }
+
+ static constexpr UnsignedType mask() noexcept
+ {
+ return ((UnsignedType(1) << width) - 1) << pos;
+ }
+
+private:
+ template<class Storage, typename... Accessors>
+ friend class QSpecialIntegerBitfieldUnion;
+ friend class QSpecialIntegerAccessor<S, pos, width, T>;
+
+ explicit QSpecialIntegerConstAccessor(Storage *storage) : storage(storage) {}
+
+ friend bool operator==(const QSpecialIntegerConstAccessor<S, pos, width, T> &i,
+ const QSpecialIntegerConstAccessor<S, pos, width, T> &j) noexcept
+ {
+ return ((i.storage->val ^ j.storage->val) & S::toSpecial(mask())) == 0;
+ }
+
+ friend bool operator!=(const QSpecialIntegerConstAccessor<S, pos, width, T> &i,
+ const QSpecialIntegerConstAccessor<S, pos, width, T> &j) noexcept
+ {
+ return ((i.storage->val ^ j.storage->val) & S::toSpecial(mask())) != 0;
+ }
+
+ Storage *storage;
+};
+
+template<class S, int pos, int width, class T>
+class QSpecialIntegerAccessor
+{
+ Q_DISABLE_COPY(QSpecialIntegerAccessor)
+public:
+ using Const = QSpecialIntegerConstAccessor<S, pos, width, T>;
+ using Storage = QSpecialIntegerStorage<S>;
+ using Type = T;
+ using UnsignedType = typename std::make_unsigned<T>::type;
+
+ QSpecialIntegerAccessor(QSpecialIntegerAccessor &&) noexcept = default;
+ QSpecialIntegerAccessor &operator=(QSpecialIntegerAccessor &&) noexcept = default;
+
+ QSpecialIntegerAccessor &operator=(Type t)
+ {
+ UnsignedType i = S::fromSpecial(storage->val);
+ i &= ~Const::mask();
+ i |= (UnsignedType(t) << pos) & Const::mask();
+ storage->val = S::toSpecial(i);
+ return *this;
+ }
+
+ operator Const() { return Const(storage); }
+
+private:
+ template<class Storage, typename... Accessors>
+ friend class QSpecialIntegerBitfieldUnion;
+
+ explicit QSpecialIntegerAccessor(Storage *storage) : storage(storage) {}
+
+ Storage *storage;
+};
+
+template<class S, typename... Accessors>
+class QSpecialIntegerBitfieldUnion
+{
+public:
+ constexpr QSpecialIntegerBitfieldUnion() = default;
+ constexpr QSpecialIntegerBitfieldUnion(QSpecialIntegerBitfieldInitializer initial)
+ : storage(initial)
+ {}
+
+ constexpr QSpecialIntegerBitfieldUnion(
+ typename QSpecialIntegerStorage<S>::UnsignedStorageType initial)
+ : storage(initial)
+ {}
+
+ template<typename A>
+ void set(typename A::Type value)
+ {
+ member<A>() = value;
+ }
+
+ template<typename A>
+ typename A::Type get() const
+ {
+ return member<A>();
+ }
+
+ typename QSpecialIntegerStorage<S>::UnsignedStorageType data() const
+ {
+ return storage.val;
+ }
+
+private:
+ template<class A, class...> struct Contains : std::false_type { };
+ template<class A, class B> struct Contains<A, B> : std::is_same<A, B> { };
+ template<class A, class B1, class... Bn>
+ struct Contains<A, B1, Bn...>
+ : std::conditional<Contains<A, B1>::value, std::true_type, Contains<A, Bn...>>::type {};
+
+ template<typename A>
+ using IsAccessor = Contains<A, Accessors...>;
+
+ template<typename A>
+ A member()
+ {
+ Q_STATIC_ASSERT(IsAccessor<A>::value);
+ return A(&storage);
+ }
+
+ template<typename A>
+ typename A::Const member() const
+ {
+ Q_STATIC_ASSERT(IsAccessor<A>::value);
+ return typename A::Const(&storage);
+ }
+
+ QSpecialIntegerStorage<S> storage;
+};
+
+template<typename T, typename... Accessors>
+using QLEIntegerBitfieldUnion
+ = QSpecialIntegerBitfieldUnion<QLittleEndianStorageType<T>, Accessors...>;
+
+template<typename T, typename... Accessors>
+using QBEIntegerBitfieldUnion
+ = QSpecialIntegerBitfieldUnion<QBigEndianStorageType<T>, Accessors...>;
+
+template<typename... Accessors>
+using qint32_le_bitfield_union = QLEIntegerBitfieldUnion<int, Accessors...>;
+template<typename... Accessors>
+using quint32_le_bitfield_union = QLEIntegerBitfieldUnion<uint, Accessors...>;
+template<typename... Accessors>
+using qint32_be_bitfield_union = QBEIntegerBitfieldUnion<int, Accessors...>;
+template<typename... Accessors>
+using quint32_be_bitfield_union = QBEIntegerBitfieldUnion<uint, Accessors...>;
+
+template<int pos, int width, typename T = int>
+using qint32_le_bitfield_member
+ = QSpecialIntegerAccessor<QLittleEndianStorageType<int>, pos, width, T>;
+template<int pos, int width, typename T = uint>
+using quint32_le_bitfield_member
+ = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width, T>;
+template<int pos, int width, typename T = int>
+using qint32_be_bitfield_member
+ = QSpecialIntegerAccessor<QBigEndianStorageType<int>, pos, width, T>;
+template<int pos, int width, typename T = uint>
+using quint32_be_bitfield_member
+ = QSpecialIntegerAccessor<QBigEndianStorageType<uint>, pos, width, T>;
QT_END_NAMESPACE
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 9755121273..dbb9469bba 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -827,14 +827,18 @@
/*!
\enum Qt::DockWidgetArea
- \value LeftDockWidgetArea
- \value RightDockWidgetArea
- \value TopDockWidgetArea
- \value BottomDockWidgetArea
- \value AllDockWidgetAreas
- \value NoDockWidgetArea
+ Represents the areas a QDockWidget can be plugged to.
+ \note A floating dock widget with tabs can be docked anywhere.
+
+ \value LeftDockWidgetArea The left dock area of a QMainWindow.
+ \value RightDockWidgetArea The right dock area of a QMainWindow.
+ \value TopDockWidgetArea The top dock area of a QMainWindow.
+ \value BottomDockWidgetArea The bottom dock area of a QMainWindow.
+ \value AllDockWidgetAreas All dock widget areas (default).
+ \value NoDockWidgetArea No dock widget areas.
\omitvalue DockWidgetArea_Mask
+ \sa QDockWidget::setAllowedAreas, QDockWidget::isAreaAllowed
*/
/*!
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 10672c1f92..25f87c7e6a 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -383,7 +383,6 @@ struct QRandomGenerator::SystemAndGlobalGenerators
constexpr SystemAndGlobalGenerators g = {};
Q_UNUSED(g);
- Q_STATIC_ASSERT(std::is_literal_type<SystemAndGlobalGenerators>::value);
#endif
}
diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp
index 595fcd2724..5c562623e2 100644
--- a/src/corelib/io/qbuffer.cpp
+++ b/src/corelib/io/qbuffer.cpp
@@ -41,6 +41,8 @@
#include <QtCore/qmetaobject.h>
#include "private/qiodevice_p.h"
+#include <limits>
+
QT_BEGIN_NAMESPACE
/** QBufferPrivate **/
@@ -212,7 +214,7 @@ QBuffer::~QBuffer()
}
/*!
- Makes QBuffer uses the QByteArray pointed to by \a
+ Makes QBuffer use the QByteArray pointed to by \a
byteArray as its internal buffer. The caller is responsible for
ensuring that \a byteArray remains valid until the QBuffer is
destroyed, or until setBuffer() is called to change the buffer.
@@ -366,7 +368,9 @@ qint64 QBuffer::size() const
bool QBuffer::seek(qint64 pos)
{
Q_D(QBuffer);
- if (pos > d->buf->size() && isWritable()) {
+ const auto oldBufSize = d->buf->size();
+ constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
+ if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
if (seek(d->buf->size())) {
const qint64 gapSize = pos - d->buf->size();
if (write(QByteArray(gapSize, 0)) != gapSize) {
@@ -377,7 +381,7 @@ bool QBuffer::seek(qint64 pos)
return false;
}
} else if (pos > d->buf->size() || pos < 0) {
- qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
+ qWarning("QBuffer::seek: Invalid pos: %lld", pos);
return false;
}
return QIODevice::seek(pos);
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 8f2361c8fc..46e661094a 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -619,7 +619,8 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result,
bool needsQuotes = false;
bool escapeNextIfDigit = false;
bool useCodec = codec && !str.startsWith(QLatin1String("@ByteArray("))
- && !str.startsWith(QLatin1String("@Variant("));
+ && !str.startsWith(QLatin1String("@Variant("))
+ && !str.startsWith(QLatin1String("@DateTime("));
int i;
int startPos = result.size();
@@ -2162,8 +2163,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\snippet settings/settings.cpp 15
- Note that type information is not preserved when reading settings from INI
- files; all values will be returned as QString.
+ Note that INI files lose the distinction between numeric data and the
+ strings used to encode them, so values written as numbers shall be read back
+ as QString. The numeric value can be recovered using \l QString::toInt(), \l
+ QString::toDouble() and related functions.
The \l{tools/settingseditor}{Settings Editor} example lets you
experiment with different settings location and with fallbacks
@@ -2446,9 +2449,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
On 32-bit Windows or from a 64-bit application on 64-bit Windows,
this works the same as specifying NativeFormat.
This enum value was added in Qt 5.7.
- \value IniFormat Store the settings in INI files. Note that type information
- is not preserved when reading settings from INI files;
- all values will be returned as QString.
+ \value IniFormat Store the settings in INI files. Note that INI files
+ lose the distinction between numeric data and the
+ strings used to encode them, so values written as
+ numbers shall be read back as QString.
\value InvalidFormat Special value returned by registerFormat().
\omitvalue CustomFormat1
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index dc6379d9fb..3d7fe43cd3 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -2601,9 +2601,12 @@ void QSortFilterProxyModel::sort(int column, Qt::SortOrder order)
/*!
\since 4.5
- \brief the column currently used for sorting
+ \return the column currently used for sorting
- This returns the most recently used sort column.
+ This returns the most recently used sort column. The default value is -1,
+ which means that this proxy model does not sort.
+
+ \sa sort()
*/
int QSortFilterProxyModel::sortColumn() const
{
@@ -2613,9 +2616,12 @@ int QSortFilterProxyModel::sortColumn() const
/*!
\since 4.5
- \brief the order currently used for sorting
+ \return the order currently used for sorting
+
+ This returns the most recently used sort order. The default value is
+ Qt::AscendingOrder.
- This returns the most recently used sort order.
+ \sa sort()
*/
Qt::SortOrder QSortFilterProxyModel::sortOrder() const
{
@@ -2890,6 +2896,8 @@ void QSortFilterProxyModel::setFilterFixedString(const QString &pattern)
QComboBox.
The default value is true.
+
+ \sa sortColumn()
*/
bool QSortFilterProxyModel::dynamicSortFilter() const
{
diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm
index e774cebcbf..99ad4ce666 100644
--- a/src/corelib/kernel/qcore_mac.mm
+++ b/src/corelib/kernel/qcore_mac.mm
@@ -117,7 +117,7 @@ bool AppleUnifiedLogger::messageHandler(QtMsgType msgType, const QMessageLogCont
const bool isDefault = !context.category || !strcmp(context.category, "default");
os_log_t log = isDefault ? OS_LOG_DEFAULT :
- cachedLog(subsystem, QString::fromLatin1(context.category));
+ os_log_create(subsystem.toLatin1().constData(), context.category);
os_log_type_t logType = logTypeForMessageType(msgType);
if (!os_log_type_enabled(log, logType))
@@ -153,29 +153,6 @@ os_log_type_t AppleUnifiedLogger::logTypeForMessageType(QtMsgType msgType)
return OS_LOG_TYPE_DEFAULT;
}
-os_log_t AppleUnifiedLogger::cachedLog(const QString &subsystem, const QString &category)
-{
- static QBasicMutex mutex;
- const auto locker = qt_scoped_lock(mutex);
-
- static QHash<QPair<QString, QString>, os_log_t> logs;
- const auto cacheKey = qMakePair(subsystem, category);
- os_log_t log = logs.value(cacheKey);
-
- if (!log) {
- log = os_log_create(subsystem.toLatin1().constData(),
- category.toLatin1().constData());
- logs.insert(cacheKey, log);
-
- // Technically we should release the os_log_t resource when done
- // with it, but since we don't know when a category is disabled
- // we keep all cached os_log_t instances until shutdown, where
- // the OS will clean them up for us.
- }
-
- return log;
-}
-
#endif // QT_USE_APPLE_UNIFIED_LOGGING
// -------------------------------------------------------------------------
diff --git a/src/corelib/kernel/qelapsedtimer.cpp b/src/corelib/kernel/qelapsedtimer.cpp
index 3bfb1f15ec..230bcac33f 100644
--- a/src/corelib/kernel/qelapsedtimer.cpp
+++ b/src/corelib/kernel/qelapsedtimer.cpp
@@ -111,18 +111,6 @@ QT_BEGIN_NAMESPACE
that the clock used is the same as QElapsedTimer (see
QElapsedTimer::clockType()).
- \section2 32-bit overflows
-
- Some of the clocks used by QElapsedTimer have a limited range and may
- overflow after hitting the upper limit (usually 32-bit). QElapsedTimer
- deals with this overflow issue and presents a consistent timing. However,
- when extracting the time since reference from QElapsedTimer, two
- different processes in the same machine may have different understanding
- of how much time has actually elapsed.
-
- The information on which clocks types may overflow and how to remedy that
- issue is documented along with the clock types.
-
\sa QTime, QTimer, QDeadlineTimer
*/
@@ -138,10 +126,13 @@ QT_BEGIN_NAMESPACE
used.
\value SystemTime The human-readable system time. This clock is not monotonic.
- \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is monotonic and does not overflow.
+ \value MonotonicClock The system's monotonic clock, usually found in Unix systems.
+ This clock is monotonic.
\value TickCounter Not used anymore.
- \value MachAbsoluteTime The Mach kernel's absolute time (\macos and iOS). This clock is monotonic and does not overflow.
- \value PerformanceCounter The performance counter provided by Windows. This clock is monotonic and does not overflow.
+ \value MachAbsoluteTime The Mach kernel's absolute time (\macos and iOS).
+ This clock is monotonic.
+ \value PerformanceCounter The performance counter provided by Windows.
+ This clock is monotonic.
\section2 SystemTime
@@ -159,8 +150,6 @@ QT_BEGIN_NAMESPACE
arbitrary point in the past. This clock type is used on Unix systems
which support POSIX monotonic clocks (\tt{_POSIX_MONOTONIC_CLOCK}).
- This clock does not overflow.
-
\section2 MachAbsoluteTime
This clock type is based on the absolute time presented by Mach kernels,
@@ -169,14 +158,14 @@ QT_BEGIN_NAMESPACE
a POSIX monotonic clock with values differing from the Mach absolute
time.
- This clock is monotonic and does not overflow.
+ This clock is monotonic.
\section2 PerformanceCounter
This clock uses the Windows functions \tt{QueryPerformanceCounter} and
\tt{QueryPerformanceFrequency} to access the system's performance counter.
- This clock is monotonic and does not overflow.
+ This clock is monotonic.
\sa clockType(), isMonotonic()
*/
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 1eb79138d9..d57bcc31cc 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2460,6 +2460,7 @@ static bool check_method_code(int code, const QObject *object,
return true;
}
+Q_DECL_COLD_FUNCTION
static void err_method_notfound(const QObject *object,
const char *method, const char *func)
{
@@ -2481,6 +2482,7 @@ static void err_method_notfound(const QObject *object,
}
+Q_DECL_COLD_FUNCTION
static void err_info_about_objects(const char * func,
const QObject * sender,
const QObject * receiver)
diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h
index e6e989abda..0c13375094 100644
--- a/src/corelib/kernel/qsharedmemory_p.h
+++ b/src/corelib/kernel/qsharedmemory_p.h
@@ -56,14 +56,20 @@
#include <QtCore/qstring.h>
#ifdef QT_NO_SHAREDMEMORY
-# ifndef QT_NO_SYSTEMSEMAPHORE
+# ifndef QT_NO_SYSTEMSEMAPHORE
+
+QT_BEGIN_NAMESPACE
+
namespace QSharedMemoryPrivate
{
int createUnixKeyFile(const QString &fileName);
QString makePlatformSafeKey(const QString &key,
const QString &prefix = QLatin1String("qipc_sharedmemory_"));
}
-#endif
+
+QT_END_NAMESPACE
+
+# endif
#else
#include "qsystemsemaphore.h"
diff --git a/src/corelib/kernel/qsharedmemory_systemv.cpp b/src/corelib/kernel/qsharedmemory_systemv.cpp
index 0ba5f65641..b9adb4300c 100644
--- a/src/corelib/kernel/qsharedmemory_systemv.cpp
+++ b/src/corelib/kernel/qsharedmemory_systemv.cpp
@@ -109,7 +109,7 @@ key_t QSharedMemoryPrivate::handle()
0 already existed
1 created
*/
-int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName)
+int QT_PREPEND_NAMESPACE(QSharedMemoryPrivate)::createUnixKeyFile(const QString &fileName)
{
int fd = qt_safe_open(QFile::encodeName(fileName).constData(),
O_EXCL | O_CREAT | O_RDWR, 0640);
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 25ce0c032f..79c7b2628c 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -222,6 +222,8 @@ void QTimer::start()
If \l singleShot is true, the timer will be activated only once.
+ \note Keeping the event loop busy with a zero-timer is bound to
+ cause trouble and highly erratic behavior of the UI.
*/
void QTimer::start(int msec)
{
diff --git a/src/corelib/serialization/qbinaryjson.cpp b/src/corelib/serialization/qbinaryjson.cpp
index 3d359f0998..8c16178c59 100644
--- a/src/corelib/serialization/qbinaryjson.cpp
+++ b/src/corelib/serialization/qbinaryjson.cpp
@@ -64,17 +64,17 @@ void MutableData::compact()
Base *base = header->root();
int reserve = 0;
- if (base->is_object) {
+ if (base->isObject()) {
auto *o = static_cast<Object *>(base);
- for (uint i = 0; i < o->length; ++i)
+ for (uint i = 0; i < o->length(); ++i)
reserve += o->entryAt(i)->usedStorage(o);
} else {
auto *a = static_cast<Array *>(base);
- for (uint i = 0; i < a->length; ++i)
+ for (uint i = 0; i < a->length(); ++i)
reserve += a->at(i)->usedStorage(a);
}
- uint size = sizeof(Base) + reserve + base->length * sizeof(offset);
+ uint size = sizeof(Base) + reserve + base->length() * sizeof(offset);
uint alloc = sizeof(Header) + size;
auto *h = reinterpret_cast<Header *>(malloc(alloc));
Q_CHECK_PTR(h);
@@ -82,16 +82,19 @@ void MutableData::compact()
h->version = 1;
Base *b = h->root();
b->size = size;
- b->is_object = header->root()->is_object;
- b->length = base->length;
+ if (header->root()->isObject())
+ b->setIsObject();
+ else
+ b->setIsArray();
+ b->setLength(base->length());
b->tableOffset = reserve + sizeof(Array);
uint offset = sizeof(Base);
- if (b->is_object) {
+ if (b->isObject()) {
const auto *o = static_cast<const Object *>(base);
auto *no = static_cast<Object *>(b);
- for (uint i = 0; i < o->length; ++i) {
+ for (uint i = 0; i < o->length(); ++i) {
no->table()[i] = offset;
const Entry *e = o->entryAt(i);
@@ -102,7 +105,7 @@ void MutableData::compact()
uint dataSize = e->value.usedStorage(o);
if (dataSize) {
memcpy(reinterpret_cast<char *>(no) + offset, e->value.data(o), dataSize);
- ne->value.value = offset;
+ ne->value.setValue(offset);
offset += dataSize;
}
}
@@ -110,14 +113,14 @@ void MutableData::compact()
const auto *a = static_cast<const Array *>(base);
auto *na = static_cast<Array *>(b);
- for (uint i = 0; i < a->length; ++i) {
+ for (uint i = 0; i < a->length(); ++i) {
const Value *v = a->at(i);
Value *nv = na->at(i);
*nv = *v;
uint dataSize = v->usedStorage(a);
if (dataSize) {
memcpy(reinterpret_cast<char *>(na) + offset, v->data(a), dataSize);
- nv->value = offset;
+ nv->setValue(offset);
offset += dataSize;
}
}
@@ -137,7 +140,7 @@ bool ConstData::isValid() const
const Base *root = header->root();
const uint maxSize = alloc - sizeof(Header);
- return root->is_object
+ return root->isObject()
? static_cast<const Object *>(root)->isValid(maxSize)
: static_cast<const Array *>(root)->isValid(maxSize);
}
@@ -145,14 +148,14 @@ bool ConstData::isValid() const
QJsonDocument ConstData::toJsonDocument() const
{
const Base *root = header->root();
- return root->is_object
+ return root->isObject()
? QJsonDocument(static_cast<const Object *>(root)->toJsonObject())
: QJsonDocument(static_cast<const Array *>(root)->toJsonArray());
}
uint Base::reserveSpace(uint dataSize, uint posInTable, uint numItems, bool replace)
{
- Q_ASSERT(posInTable <= length);
+ Q_ASSERT(posInTable <= length());
if (size + dataSize >= Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure %d %d %d",
uint(size), dataSize, Value::MaxSize);
@@ -162,10 +165,10 @@ uint Base::reserveSpace(uint dataSize, uint posInTable, uint numItems, bool repl
offset off = tableOffset;
// move table to new position
if (replace) {
- memmove(reinterpret_cast<char *>(table()) + dataSize, table(), length * sizeof(offset));
+ memmove(reinterpret_cast<char *>(table()) + dataSize, table(), length() * sizeof(offset));
} else {
memmove(reinterpret_cast<char *>(table() + posInTable + numItems) + dataSize,
- table() + posInTable, (length - posInTable) * sizeof(offset));
+ table() + posInTable, (length() - posInTable) * sizeof(offset));
memmove(reinterpret_cast<char *>(table()) + dataSize, table(), posInTable * sizeof(offset));
}
tableOffset += dataSize;
@@ -173,7 +176,7 @@ uint Base::reserveSpace(uint dataSize, uint posInTable, uint numItems, bool repl
table()[posInTable + i] = off;
size += dataSize;
if (!replace) {
- length += numItems;
+ setLength(length() + numItems);
size += numItems * sizeof(offset);
}
return off;
@@ -182,7 +185,7 @@ uint Base::reserveSpace(uint dataSize, uint posInTable, uint numItems, bool repl
uint Object::indexOf(QStringView key, bool *exists) const
{
uint min = 0;
- uint n = length;
+ uint n = length();
while (n > 0) {
uint half = n >> 1;
uint middle = min + half;
@@ -193,7 +196,7 @@ uint Object::indexOf(QStringView key, bool *exists) const
n -= half + 1;
}
}
- if (min < length && *entryAt(min) == key) {
+ if (min < length() && *entryAt(min) == key) {
*exists = true;
return min;
}
@@ -204,7 +207,7 @@ uint Object::indexOf(QStringView key, bool *exists) const
QJsonObject Object::toJsonObject() const
{
QJsonObject object;
- for (uint i = 0; i < length; ++i) {
+ for (uint i = 0; i < length(); ++i) {
const Entry *e = entryAt(i);
object.insert(e->key(), e->value.toJsonValue(this));
}
@@ -213,11 +216,11 @@ QJsonObject Object::toJsonObject() const
bool Object::isValid(uint maxSize) const
{
- if (size > maxSize || tableOffset + length * sizeof(offset) > size)
+ if (size > maxSize || tableOffset + length() * sizeof(offset) > size)
return false;
QString lastKey;
- for (uint i = 0; i < length; ++i) {
+ for (uint i = 0; i < length(); ++i) {
if (table()[i] + sizeof(Entry) >= tableOffset)
return false;
const Entry *e = entryAt(i);
@@ -237,18 +240,18 @@ QJsonArray Array::toJsonArray() const
{
QJsonArray array;
const offset *values = table();
- for (uint i = 0; i < length; ++i)
+ for (uint i = 0; i < length(); ++i)
array.append(reinterpret_cast<const Value *>(values + i)->toJsonValue(this));
return array;
}
bool Array::isValid(uint maxSize) const
{
- if (size > maxSize || tableOffset + length * sizeof(offset) > size)
+ if (size > maxSize || tableOffset + length() * sizeof(offset) > size)
return false;
const offset *values = table();
- for (uint i = 0; i < length; ++i) {
+ for (uint i = 0; i < length(); ++i) {
if (!reinterpret_cast<const Value *>(values + i)->isValid(this))
return false;
}
@@ -258,14 +261,14 @@ bool Array::isValid(uint maxSize) const
uint Value::usedStorage(const Base *b) const
{
uint s = 0;
- switch (type) {
+ switch (type()) {
case QJsonValue::Double:
- if (!latinOrIntValue)
+ if (!isLatinOrIntValue())
s = sizeof(double);
break;
case QJsonValue::String: {
const char *d = data(b);
- s = latinOrIntValue
+ s = isLatinOrIntValue()
? (sizeof(ushort)
+ qFromLittleEndian(*reinterpret_cast<const ushort *>(d)))
: (sizeof(int)
@@ -286,7 +289,7 @@ uint Value::usedStorage(const Base *b) const
QJsonValue Value::toJsonValue(const Base *b) const
{
- switch (type) {
+ switch (type()) {
case QJsonValue::Null:
return QJsonValue(QJsonValue::Null);
case QJsonValue::Bool:
@@ -314,24 +317,24 @@ inline bool isValidValueOffset(uint offset, uint tableOffset)
bool Value::isValid(const Base *b) const
{
- switch (type) {
+ switch (type()) {
case QJsonValue::Null:
case QJsonValue::Bool:
return true;
case QJsonValue::Double:
- return latinOrIntValue || isValidValueOffset(value, b->tableOffset);
+ return isLatinOrIntValue() || isValidValueOffset(value(), b->tableOffset);
case QJsonValue::String:
- if (!isValidValueOffset(value, b->tableOffset))
+ if (!isValidValueOffset(value(), b->tableOffset))
return false;
- if (latinOrIntValue)
- return asLatin1String(b).isValid(b->tableOffset - value);
- return asString(b).isValid(b->tableOffset - value);
+ if (isLatinOrIntValue())
+ return asLatin1String(b).isValid(b->tableOffset - value());
+ return asString(b).isValid(b->tableOffset - value());
case QJsonValue::Array:
- return isValidValueOffset(value, b->tableOffset)
- && static_cast<const Array *>(base(b))->isValid(b->tableOffset - value);
+ return isValidValueOffset(value(), b->tableOffset)
+ && static_cast<const Array *>(base(b))->isValid(b->tableOffset - value());
case QJsonValue::Object:
- return isValidValueOffset(value, b->tableOffset)
- && static_cast<const Object *>(base(b))->isValid(b->tableOffset - value);
+ return isValidValueOffset(value(), b->tableOffset)
+ && static_cast<const Object *>(base(b))->isValid(b->tableOffset - value());
default:
return false;
}
diff --git a/src/corelib/serialization/qbinaryjson_p.h b/src/corelib/serialization/qbinaryjson_p.h
index 132c36f227..6502f1fbd2 100644
--- a/src/corelib/serialization/qbinaryjson_p.h
+++ b/src/corelib/serialization/qbinaryjson_p.h
@@ -136,11 +136,15 @@ using qle_ushort = q_littleendian<unsigned short>;
using qle_int = q_littleendian<int>;
using qle_uint = q_littleendian<unsigned int>;
-template<int pos, int width>
-using qle_bitfield = QLEIntegerBitfield<uint, pos, width>;
+template<typename... Accessors>
+using qle_bitfield = QLEIntegerBitfieldUnion<uint, Accessors...>;
template<int pos, int width>
-using qle_signedbitfield = QLEIntegerBitfield<int, pos, width>;
+using qle_bitfield_accessor
+ = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width>;
+template<int pos, int width>
+using qle_signedbitfield_accessor
+ = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width, int>;
using offset = qle_uint;
@@ -316,19 +320,24 @@ static inline void copyString(char *dest, QStringView str, bool compress)
*/
class Base
{
+private:
+ using IsObjectAccessor = qle_bitfield_accessor<0, 1>;
+ using LengthAccessor = qle_bitfield_accessor<1, 31>;
public:
qle_uint size;
- union {
- uint _dummy;
- qle_bitfield<0, 1> is_object;
- qle_bitfield<1, 31> length;
- };
+ qle_bitfield<IsObjectAccessor, LengthAccessor> isObjectAndLength;
offset tableOffset;
// content follows here
- bool isObject() const { return !!is_object; }
+ void setIsObject() { isObjectAndLength.set<IsObjectAccessor>(1); }
+ bool isObject() const { return !!isObjectAndLength.get<IsObjectAccessor>(); }
+
+ void setIsArray() { isObjectAndLength.set<IsObjectAccessor>(0); }
bool isArray() const { return !isObject(); }
+ void setLength(uint length) { isObjectAndLength.set<LengthAccessor>(length); }
+ uint length() const { return isObjectAndLength.get<LengthAccessor>(); }
+
offset *table()
{
return reinterpret_cast<offset *>(reinterpret_cast<char *>(this) + tableOffset);
@@ -372,39 +381,46 @@ public:
class Value
{
+private:
+ using TypeAccessor = qle_bitfield_accessor<0, 3>;
+ using LatinOrIntValueAccessor = qle_bitfield_accessor<3, 1>;
+ using LatinKeyAccessor = qle_bitfield_accessor<4, 1>;
+ using ValueAccessor = qle_bitfield_accessor<5, 27>;
+ using IntValueAccessor = qle_signedbitfield_accessor<5, 27>;
+ qle_bitfield<
+ TypeAccessor,
+ LatinOrIntValueAccessor,
+ LatinKeyAccessor,
+ ValueAccessor,
+ IntValueAccessor
+ > m_data;
+ int intValue() const { return m_data.get<IntValueAccessor>(); }
+
public:
enum {
MaxSize = (1 << 27) - 1
};
- union {
- uint _dummy;
- qle_bitfield<0, 3> type;
- qle_bitfield<3, 1> latinOrIntValue;
- qle_bitfield<4, 1> latinKey;
- qle_bitfield<5, 27> value;
- qle_signedbitfield<5, 27> int_value;
- };
inline const char *data(const Base *b) const
{
- return reinterpret_cast<const char *>(b) + value;
+ return reinterpret_cast<const char *>(b) + value();
}
uint usedStorage(const Base *b) const;
bool toBoolean() const
{
- Q_ASSERT(type == QJsonValue::Bool);
- return value != 0;
+ Q_ASSERT(type() == QJsonValue::Bool);
+ return value() != 0;
}
double toDouble(const Base *b) const
{
- Q_ASSERT(type == QJsonValue::Double);
- if (latinOrIntValue)
- return int_value;
+ Q_ASSERT(type() == QJsonValue::Double);
+ if (isLatinOrIntValue())
+ return intValue();
- auto i = qFromLittleEndian<quint64>(reinterpret_cast<const uchar *>(b) + value);
+ auto i = qFromLittleEndian<quint64>(reinterpret_cast<const uchar *>(b) + value());
double d;
memcpy(&d, &i, sizeof(double));
return d;
@@ -412,26 +428,26 @@ public:
QString toString(const Base *b) const
{
- return latinOrIntValue
+ return isLatinOrIntValue()
? asLatin1String(b).toString()
: asString(b).toString();
}
String asString(const Base *b) const
{
- Q_ASSERT(type == QJsonValue::String && !latinOrIntValue);
+ Q_ASSERT(type() == QJsonValue::String && !isLatinOrIntValue());
return String(data(b));
}
Latin1String asLatin1String(const Base *b) const
{
- Q_ASSERT(type == QJsonValue::String && latinOrIntValue);
+ Q_ASSERT(type() == QJsonValue::String && isLatinOrIntValue());
return Latin1String(data(b));
}
const Base *base(const Base *b) const
{
- Q_ASSERT(type == QJsonValue::Array || type == QJsonValue::Object);
+ Q_ASSERT(type() == QJsonValue::Array || type() == QJsonValue::Object);
return reinterpret_cast<const Base *>(data(b));
}
@@ -441,6 +457,15 @@ public:
static uint requiredStorage(const QBinaryJsonValue &v, bool *compressed);
static uint valueToStore(const QBinaryJsonValue &v, uint offset);
static void copyData(const QBinaryJsonValue &v, char *dest, bool compressed);
+
+ void setIsLatinKey(bool isLatinKey) { m_data.set<LatinKeyAccessor>(isLatinKey); }
+ bool isLatinKey() const { return m_data.get<LatinKeyAccessor>(); }
+ void setIsLatinOrIntValue(bool v) { m_data.set<LatinOrIntValueAccessor>(v); }
+ bool isLatinOrIntValue() const { return m_data.get<LatinOrIntValueAccessor>(); }
+ void setType(uint type) { m_data.set<TypeAccessor>(type); }
+ uint type() const { return m_data.get<TypeAccessor>(); }
+ void setValue(uint value) { m_data.set<ValueAccessor>(value); }
+ uint value() const { return m_data.get<ValueAccessor>(); }
};
class Entry {
@@ -452,7 +477,7 @@ public:
uint size() const
{
uint s = sizeof(Entry);
- if (value.latinKey)
+ if (value.isLatinKey())
s += shallowLatin1Key().byteSize();
else
s += shallowKey().byteSize();
@@ -466,19 +491,19 @@ public:
String shallowKey() const
{
- Q_ASSERT(!value.latinKey);
+ Q_ASSERT(!value.isLatinKey());
return String(reinterpret_cast<const char *>(this) + sizeof(Entry));
}
Latin1String shallowLatin1Key() const
{
- Q_ASSERT(value.latinKey);
+ Q_ASSERT(value.isLatinKey());
return Latin1String(reinterpret_cast<const char *>(this) + sizeof(Entry));
}
QString key() const
{
- return value.latinKey
+ return value.isLatinKey()
? shallowLatin1Key().toString()
: shallowKey().toString();
}
@@ -488,21 +513,21 @@ public:
if (maxSize < sizeof(Entry))
return false;
maxSize -= sizeof(Entry);
- return value.latinKey
+ return value.isLatinKey()
? shallowLatin1Key().isValid(maxSize)
: shallowKey().isValid(maxSize);
}
bool operator ==(QStringView key) const
{
- return value.latinKey
+ return value.isLatinKey()
? (shallowLatin1Key().toQLatin1String() == key)
: (shallowKey() == key);
}
bool operator >=(QStringView key) const
{
- return value.latinKey
+ return value.isLatinKey()
? (shallowLatin1Key().toQLatin1String() >= key)
: (shallowKey().toString() >= key);
}
@@ -560,9 +585,12 @@ public:
header->version = 1;
Base *b = header->root();
b->size = sizeof(Base);
- b->is_object = (valueType == QJsonValue::Object);
+ if (valueType == QJsonValue::Object)
+ b->setIsObject();
+ else
+ b->setIsArray();
b->tableOffset = sizeof(Base);
- b->length = 0;
+ b->setLength(0);
}
~MutableData()
diff --git a/src/corelib/serialization/qbinaryjsonarray.cpp b/src/corelib/serialization/qbinaryjsonarray.cpp
index 68937fe17d..dfbe94db84 100644
--- a/src/corelib/serialization/qbinaryjsonarray.cpp
+++ b/src/corelib/serialization/qbinaryjsonarray.cpp
@@ -63,7 +63,7 @@ QBinaryJsonArray QBinaryJsonArray::fromJsonArray(const QJsonArray &array)
void QBinaryJsonArray::append(const QBinaryJsonValue &value)
{
- const uint i = a ? a->length : 0;
+ const uint i = a ? a->length() : 0;
bool compressed;
uint valueSize = QBinaryJsonPrivate::Value::requiredStorage(value, &compressed);
@@ -71,7 +71,7 @@ void QBinaryJsonArray::append(const QBinaryJsonValue &value)
if (!detach(valueSize + sizeof(QBinaryJsonPrivate::Value)))
return;
- if (!a->length)
+ if (!a->length())
a->tableOffset = sizeof(QBinaryJsonPrivate::Array);
uint valueOffset = a->reserveSpace(valueSize, i, 1, false);
@@ -79,10 +79,10 @@ void QBinaryJsonArray::append(const QBinaryJsonValue &value)
return;
QBinaryJsonPrivate::Value *v = a->at(i);
- v->type = (value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
- v->latinOrIntValue = compressed;
- v->latinKey = false;
- v->value = QBinaryJsonPrivate::Value::valueToStore(value, valueOffset);
+ v->setType(value.t == QJsonValue::Undefined ? QJsonValue::Null : value.t);
+ v->setIsLatinOrIntValue(compressed);
+ v->setIsLatinKey(false);
+ v->setValue(QBinaryJsonPrivate::Value::valueToStore(value, valueOffset));
if (valueSize) {
QBinaryJsonPrivate::Value::copyData(value, reinterpret_cast<char *>(a) + valueOffset,
compressed);
diff --git a/src/corelib/serialization/qbinaryjsonobject.cpp b/src/corelib/serialization/qbinaryjsonobject.cpp
index 3186ab6087..a9e830228e 100644
--- a/src/corelib/serialization/qbinaryjsonobject.cpp
+++ b/src/corelib/serialization/qbinaryjsonobject.cpp
@@ -74,7 +74,7 @@ void QBinaryJsonObject::insert(const QString &key, const QBinaryJsonValue &value
if (!detach(requiredSize + sizeof(QBinaryJsonPrivate::offset))) // offset for the new index entry
return;
- if (!o->length)
+ if (!o->length())
o->tableOffset = sizeof(QBinaryJsonPrivate::Object);
bool keyExists = false;
@@ -87,18 +87,18 @@ void QBinaryJsonObject::insert(const QString &key, const QBinaryJsonValue &value
return;
QBinaryJsonPrivate::Entry *e = o->entryAt(pos);
- e->value.type = value.t;
- e->value.latinKey = latinKey;
- e->value.latinOrIntValue = latinOrIntValue;
- e->value.value = QBinaryJsonPrivate::Value::valueToStore(
- value, reinterpret_cast<char *>(e) - reinterpret_cast<char *>(o) + valueOffset);
+ e->value.setType(value.t);
+ e->value.setIsLatinKey(latinKey);
+ e->value.setIsLatinOrIntValue(latinOrIntValue);
+ e->value.setValue(QBinaryJsonPrivate::Value::valueToStore(
+ value, reinterpret_cast<char *>(e) - reinterpret_cast<char *>(o) + valueOffset));
QBinaryJsonPrivate::copyString(reinterpret_cast<char *>(e + 1), key, latinKey);
if (valueSize) {
QBinaryJsonPrivate::Value::copyData(value, reinterpret_cast<char *>(e) + valueOffset,
latinOrIntValue);
}
- if (d->compactionCounter > 32U && d->compactionCounter >= unsigned(o->length) / 2U)
+ if (d->compactionCounter > 32U && d->compactionCounter >= unsigned(o->length()) / 2U)
compact();
}
diff --git a/src/corelib/serialization/qbinaryjsonvalue.cpp b/src/corelib/serialization/qbinaryjsonvalue.cpp
index 5e3a01ad38..b1636b331e 100644
--- a/src/corelib/serialization/qbinaryjsonvalue.cpp
+++ b/src/corelib/serialization/qbinaryjsonvalue.cpp
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
QBinaryJsonValue::QBinaryJsonValue(QBinaryJsonPrivate::MutableData *data,
QBinaryJsonPrivate::Base *parent,
const QBinaryJsonPrivate::Value &v)
- : t(QJsonValue::Type(uint(v.type)))
+ : t(QJsonValue::Type(uint(v.type())))
{
switch (t) {
case QJsonValue::Undefined:
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index b2f846544d..7cd457ba3a 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -980,7 +980,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
{
int pos = textBuffer.size();
- int oldLineNumber = lineNumber;
+ const auto oldLineNumber = lineNumber;
uint c;
while ((c = getChar()) != StreamEOF) {
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g
index b623de9505..4321fed68a 100644
--- a/src/corelib/serialization/qxmlstream.g
+++ b/src/corelib/serialization/qxmlstream.g
@@ -557,6 +557,7 @@ bool QXmlStreamReaderPrivate::parse()
setType(QXmlStreamReader::EndElement);
Tag &tag = tagStack_pop();
namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ prefix = tag.namespaceDeclaration.prefix;
name = tag.name;
qualifiedName = tag.qualifiedName;
isEmptyElement = false;
@@ -1617,6 +1618,7 @@ etag ::= LANGLE SLASH qname space_opt RANGLE;
Tag &tag = tagStack_pop();
namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ prefix = tag.namespaceDeclaration.prefix;
name = tag.name;
qualifiedName = tag.qualifiedName;
if (qualifiedName != symName(3))
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
index 103b123b10..e5bde7b98e 100644
--- a/src/corelib/serialization/qxmlstream_p.h
+++ b/src/corelib/serialization/qxmlstream_p.h
@@ -1046,6 +1046,7 @@ bool QXmlStreamReaderPrivate::parse()
setType(QXmlStreamReader::EndElement);
Tag &tag = tagStack_pop();
namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ prefix = tag.namespaceDeclaration.prefix;
name = tag.name;
qualifiedName = tag.qualifiedName;
isEmptyElement = false;
@@ -1798,6 +1799,7 @@ bool QXmlStreamReaderPrivate::parse()
namespaceUri = tag.namespaceDeclaration.namespaceUri;
name = tag.name;
qualifiedName = tag.qualifiedName;
+ prefix = tag.namespaceDeclaration.prefix;
if (qualifiedName != symName(3))
raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
} break;
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index 8c28507d5a..63637ae05b 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -155,7 +155,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
*/
QReadWriteLock::~QReadWriteLock()
{
- auto d = d_ptr.loadRelaxed();
+ auto d = d_ptr.loadAcquire();
if (isUncontendedLocked(d)) {
qWarning("QReadWriteLock: destroying locked QReadWriteLock");
return;
@@ -445,7 +445,7 @@ void QReadWriteLock::unlock()
/*! \internal Helper for QWaitCondition::wait */
QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
{
- QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
+ QReadWriteLockPrivate *d = d_ptr.loadAcquire();
switch (quintptr(d) & StateMask) {
case StateLockedForRead: return LockedForRead;
case StateLockedForWrite: return LockedForWrite;
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 1d01fc1b28..3ecdee3747 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -354,7 +354,12 @@ void QSemaphore::release(int n)
quintptr nn = unsigned(n);
if (futexHasWaiterCount)
nn |= quint64(nn) << 32; // token count replicated in high word
- quintptr prevValue = u.fetchAndAddRelease(nn);
+ quintptr prevValue = u.loadRelaxed();
+ quintptr newValue;
+ do { // loop just to ensure the operations are done atomically
+ newValue = prevValue + nn;
+ newValue &= (futexNeedsWakeAllBit - 1);
+ } while (!u.testAndSetRelease(prevValue, newValue, prevValue));
if (futexNeedsWake(prevValue)) {
#ifdef FUTEX_OP
if (futexHasWaiterCount) {
@@ -376,7 +381,6 @@ void QSemaphore::release(int n)
quint32 oparg = 0;
quint32 cmp = FUTEX_OP_CMP_NE;
quint32 cmparg = 0;
- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg));
return;
}
@@ -388,7 +392,6 @@ void QSemaphore::release(int n)
// its acquisition anyway, so it has to wait;
// 2) it did not see the new counter value, in which case its
// futexWait will fail.
- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
if (futexHasWaiterCount) {
futexWakeAll(*futexLow32(&u));
futexWakeAll(*futexHigh32(&u));
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index c30fd046a4..c1952f9bf5 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -90,6 +90,7 @@ enum {
MSECS_PER_HOUR = 3600000,
SECS_PER_MIN = 60,
MSECS_PER_MIN = 60000,
+ MSECS_PER_SEC = 1000,
TIME_T_MAX = 2145916799, // int maximum 2037-12-31T23:59:59 UTC
JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1)
};
@@ -4532,7 +4533,7 @@ QString QDateTime::toString(const QString &format, QCalendar cal) const
#endif // datestring
-static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date, QTime *time)
+static inline void massageAdjustedDateTime(QDateTimeData &d, QDate *date, QTime *time)
{
/*
If we have just adjusted to a day with a DST transition, our given time
@@ -4547,16 +4548,44 @@ static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date,
answers do then differ only in DST-ness.)
*/
auto spec = getSpec(d);
+ if (spec == Qt::OffsetFromUTC || spec == Qt::UTC) {
+ setDateTime(d, *date, *time);
+ checkValidDateTime(d);
+ return;
+ }
+ auto dst = extractDaylightStatus(getStatus(d));
+ qint64 utc = 0;
+ qint64 local = timeToMSecs(*date, *time);
if (spec == Qt::LocalTime) {
- QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime;
- localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time);
+ utc = localMSecsToEpochMSecs(local, &dst, date, time);
#if QT_CONFIG(timezone)
} else if (spec == Qt::TimeZone && d.d->m_timeZone.isValid()) {
- QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time),
- d.d->m_timeZone,
- QDateTimePrivate::UnknownDaylightTime,
- date, time);
+ utc = QDateTimePrivate::zoneMSecsToEpochMSecs(local, d.d->m_timeZone, dst, date, time);
+ // update dst, as it's passed to zoneMSecsToEpochMSecs() by value
+ dst = d.d->m_timeZone.isDaylightTime(QDateTime::fromMSecsSinceEpoch(utc))
+ ? QDateTimePrivate::DaylightTime : QDateTimePrivate::StandardTime;
#endif // timezone
+ } else {
+ dst = QDateTimePrivate::UnknownDaylightTime;
+ }
+
+ setDateTime(d, *date, *time);
+
+ auto status = getStatus(d); // Updated by setDateTime()
+ const bool ok = (dst != QDateTimePrivate::UnknownDaylightTime
+ && (status & QDateTimePrivate::ValidDate)
+ && (status & QDateTimePrivate::ValidTime));
+ if (ok)
+ status = mergeDaylightStatus(status | QDateTimePrivate::ValidDateTime, dst);
+ else
+ status &= ~QDateTimePrivate::ValidDateTime;
+
+ if (status & QDateTimePrivate::ShortData) {
+ d.data.status = status;
+ } else {
+ d->m_status = status;
+ if (ok)
+ d->m_offsetFromUtc = (local - utc) / MSECS_PER_SEC;
}
}
@@ -4582,7 +4611,6 @@ QDateTime QDateTime::addDays(qint64 ndays) const
QTime &time = p.second;
date = date.addDays(ndays);
massageAdjustedDateTime(dt.d, &date, &time);
- setDateTime(dt.d, date, time);
return dt;
}
@@ -4608,7 +4636,6 @@ QDateTime QDateTime::addMonths(int nmonths) const
QTime &time = p.second;
date = date.addMonths(nmonths);
massageAdjustedDateTime(dt.d, &date, &time);
- setDateTime(dt.d, date, time);
return dt;
}
@@ -4634,7 +4661,6 @@ QDateTime QDateTime::addYears(int nyears) const
QTime &time = p.second;
date = date.addYears(nyears);
massageAdjustedDateTime(dt.d, &date, &time);
- setDateTime(dt.d, date, time);
return dt;
}
diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp
index c5e0493de5..ce28c6d034 100644
--- a/src/corelib/time/qdatetimeparser.cpp
+++ b/src/corelib/time/qdatetimeparser.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -761,6 +761,11 @@ QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
const int sectionmaxsize = sectionMaxSize(sectionIndex);
QStringRef sectionTextRef = text->midRef(offset, sectionmaxsize);
+ // If the fields we've read thus far imply a time in a spring-forward,
+ // coerce to a nearby valid time:
+ const QDateTime defaultValue = currentValue.isValid() ? currentValue
+ : QDateTime::fromMSecsSinceEpoch(currentValue.toMSecsSinceEpoch());
+
QDTPDEBUG << "sectionValue for" << sn.name()
<< "with text" << *text << "and (at" << offset
<< ") st:" << sectionTextRef;
@@ -793,7 +798,7 @@ QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
text->replace(offset, used, sectiontext.constData(), used);
break; }
case TimeZoneSection:
- result = findTimeZone(sectionTextRef, currentValue,
+ result = findTimeZone(sectionTextRef, defaultValue,
absoluteMax(sectionIndex),
absoluteMin(sectionIndex));
break;
@@ -805,7 +810,7 @@ QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
int num = 0, used = 0;
if (sn.type == MonthSection) {
const QDate minDate = getMinimum().date();
- const int year = currentValue.date().year(calendar);
+ const int year = defaultValue.date().year(calendar);
const int min = (year == minDate.year(calendar)) ? minDate.month(calendar) : 1;
num = findMonth(sectiontext.toLower(), min, sectionIndex, year, &sectiontext, &used);
} else {
@@ -887,7 +892,7 @@ QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
else
QDTPDEBUG << "invalid because" << last << "is less than absoluteMin" << absMin;
} else if (unfilled && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) {
- if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {
+ if (skipToNextSection(sectionIndex, defaultValue, digitsStr)) {
const int missingZeroes = sectionmaxsize - digitsStr.size();
result = ParsedSection(Acceptable, last, sectionmaxsize, missingZeroes);
text->insert(offset, QString(missingZeroes, QLatin1Char('0')));
diff --git a/src/corelib/time/qtimezoneprivate_android.cpp b/src/corelib/time/qtimezoneprivate_android.cpp
index da82832455..3609c65d55 100644
--- a/src/corelib/time/qtimezoneprivate_android.cpp
+++ b/src/corelib/time/qtimezoneprivate_android.cpp
@@ -86,17 +86,10 @@ QAndroidTimeZonePrivate::~QAndroidTimeZonePrivate()
static QJNIObjectPrivate getDisplayName(QJNIObjectPrivate zone, jint style, jboolean dst,
const QLocale &locale)
{
- QJNIObjectPrivate jlanguage
- = QJNIObjectPrivate::fromString(QLocale::languageToString(locale.language()));
- QJNIObjectPrivate jcountry
- = QJNIObjectPrivate::fromString(QLocale::countryToString(locale.country()));
- QJNIObjectPrivate
- jvariant = QJNIObjectPrivate::fromString(QLocale::scriptToString(locale.script()));
- QJNIObjectPrivate jlocale("java.util.Locale",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
- static_cast<jstring>(jlanguage.object()),
- static_cast<jstring>(jcountry.object()),
- static_cast<jstring>(jvariant.object()));
+ QJNIObjectPrivate jbcpTag = QJNIObjectPrivate::fromString(locale.bcp47Name());
+ QJNIObjectPrivate jlocale = QJNIObjectPrivate::callStaticObjectMethod(
+ "java/util/Locale", "forLanguageTag", "(Ljava/lang/String;)Ljava/util/Locale;",
+ static_cast<jstring>(jbcpTag.object()));
return zone.callObjectMethod("getDisplayName",
"(ZILjava/util/Locale;)Ljava/lang/String;",
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index a24b689181..7becff8700 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -1400,7 +1400,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
}
// we can create the refcount data because it doesn't exist
- ExternalRefCountData *x = new ExternalRefCountData(Qt::Uninitialized);
+ ExternalRefCountData *x = ::new ExternalRefCountData(Qt::Uninitialized);
x->strongref.storeRelaxed(-1);
x->weakref.storeRelaxed(2); // the QWeakPointer that called us plus the QObject itself
@@ -1411,7 +1411,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
// ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
// only execute this if Q_ASSERTs are enabled
Q_ASSERT((x->weakref.storeRelaxed(0), true));
- delete x;
+ ::delete x;
ret->weakref.ref();
}
return ret;
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 618b31e391..d262e4ebc9 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -156,6 +156,12 @@ namespace QtSharedPointer {
inline void checkQObjectShared(...) { }
inline void setQObjectShared(...) { }
+ // Normally, only subclasses of ExternalRefCountData are allocated
+ // One exception exists in getAndRef; that uses the global operator new
+ // to prevent a mismatch with the custom operator delete
+ inline void *operator new(std::size_t) = delete;
+ // placement new
+ inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
inline void operator delete(void *ptr) { ::operator delete(ptr); }
inline void operator delete(void *, void *) { }
};