summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/Qt5CoreConfigExtras.cmake.in15
-rw-r--r--src/corelib/animation/qvariantanimation.cpp6
-rw-r--r--src/corelib/doc/src/animation.qdoc11
-rw-r--r--src/corelib/global/global.pri23
-rw-r--r--src/corelib/global/qcompilerdetection.h7
-rw-r--r--src/corelib/global/qendian.h24
-rw-r--r--src/corelib/global/qendian.qdoc23
-rw-r--r--src/corelib/global/qhooks.cpp2
-rw-r--r--src/corelib/global/qsystemdetection.h4
-rw-r--r--src/corelib/io/io.pri1
-rw-r--r--src/corelib/io/qdebug.cpp9
-rw-r--r--src/corelib/io/qfileinfo.cpp4
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp4
-rw-r--r--src/corelib/io/qfilesystemwatcher_kqueue.cpp2
-rw-r--r--src/corelib/io/qlockfile_unix.cpp43
-rw-r--r--src/corelib/io/qlockfile_win.cpp6
-rw-r--r--src/corelib/io/qprocess.cpp10
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp2
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp2
-rw-r--r--src/corelib/json/qjson_p.h4
-rw-r--r--src/corelib/json/qjsonobject.cpp4
-rw-r--r--src/corelib/json/qjsonvalue.cpp24
-rw-r--r--src/corelib/kernel/qcore_unix.cpp10
-rw-r--r--src/corelib/kernel/qcore_unix_p.h10
-rw-r--r--src/corelib/kernel/qobject.cpp2
-rw-r--r--src/corelib/kernel/qobject.h29
-rw-r--r--src/corelib/kernel/qobject_impl.h29
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h381
-rw-r--r--src/corelib/mimetypes/qmimemagicrule.cpp3
-rw-r--r--src/corelib/thread/qmutex_linux.cpp2
-rw-r--r--src/corelib/tools/qarraydata.cpp34
-rw-r--r--src/corelib/tools/qbitarray.cpp26
-rw-r--r--src/corelib/tools/qbytearray.cpp112
-rw-r--r--src/corelib/tools/qcryptographichash.cpp20
-rw-r--r--src/corelib/tools/qdatetime.cpp2
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp23
-rw-r--r--src/corelib/tools/qdatetimeparser_p.h14
-rw-r--r--src/corelib/tools/qhash.cpp9
-rw-r--r--src/corelib/tools/qlist.cpp29
-rw-r--r--src/corelib/tools/qmessageauthenticationcode.cpp20
-rw-r--r--src/corelib/tools/qsimd.cpp22
-rw-r--r--src/corelib/tools/qstring.cpp16
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp214
-rw-r--r--src/corelib/tools/qtools_p.h14
-rw-r--r--src/corelib/tools/qvector.h8
-rw-r--r--src/corelib/xml/qxmlstream.cpp18
46 files changed, 545 insertions, 732 deletions
diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index a5ed8b2ea3..f492148a50 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -46,6 +46,21 @@ if (NOT TARGET Qt5::rcc)
)
endif()
+if (NOT TARGET Qt5::qdoc)
+ add_executable(Qt5::qdoc IMPORTED)
+
+!!IF isEmpty(CMAKE_BIN_DIR_IS_ABSOLUTE)
+ set(imported_location \"${_qt5Core_install_prefix}/$${CMAKE_BIN_DIR}qdoc$$CMAKE_BIN_SUFFIX\")
+!!ELSE
+ set(imported_location \"$${CMAKE_BIN_DIR}qdoc$$CMAKE_BIN_SUFFIX\")
+!!ENDIF
+ _qt5_Core_check_file_exists(${imported_location})
+
+ set_target_properties(Qt5::qdoc PROPERTIES
+ IMPORTED_LOCATION ${imported_location}
+ )
+endif()
+
set(Qt5Core_QMAKE_EXECUTABLE Qt5::qmake)
set(Qt5Core_MOC_EXECUTABLE Qt5::moc)
set(Qt5Core_RCC_EXECUTABLE Qt5::rcc)
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index a783bcc31e..7117092c54 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -54,15 +54,13 @@ QT_BEGIN_NAMESPACE
\class QVariantAnimation
\inmodule QtCore
\ingroup animation
- \brief The QVariantAnimation class provides an abstract base class for animations.
+ \brief The QVariantAnimation class provides a base class for animations.
\since 4.6
This class is part of \l{The Animation Framework}. It serves as a
base class for property and item animations, with functions for
shared functionality.
- QVariantAnimation cannot be used directly as it is an abstract
- class; it has a pure virtual method called updateCurrentValue().
The class performs interpolation over
\l{QVariant}s, but leaves using the interpolated values to its
subclasses. Currently, Qt provides QPropertyAnimation, which
@@ -75,7 +73,7 @@ QT_BEGIN_NAMESPACE
start the animation. QVariantAnimation will interpolate the
property of the target object and emit valueChanged(). To react to
a change in the current value you have to reimplement the
- updateCurrentValue() virtual function.
+ updateCurrentValue() virtual function or connect to said signal.
It is also possible to set values at specified steps situated
between the start and end value. The interpolation will then
diff --git a/src/corelib/doc/src/animation.qdoc b/src/corelib/doc/src/animation.qdoc
index 02eb5a97c6..4e71ed4268 100644
--- a/src/corelib/doc/src/animation.qdoc
+++ b/src/corelib/doc/src/animation.qdoc
@@ -118,11 +118,12 @@
\section1 Animating Qt Properties
- As mentioned in the previous section, the QPropertyAnimation class
- can interpolate over Qt properties. It is this class that should
- be used for animation of values; in fact, its superclass,
- QVariantAnimation, is an abstract class, and cannot be used
- directly.
+ As mentioned in the previous section, the QPropertyAnimation class can
+ interpolate over Qt properties. It is often this class that should be used
+ for animation of values; in fact, its superclass, QVariantAnimation, has an
+ empty implementation of \l{QAbstractAnimation::}{updateCurrentValue()}, and
+ does not change any value unless we change it ourselves on the
+ \l{QVariantAnimation::valueChanged()}{valueChanged signal}.
A major reason we chose to animate Qt properties is that it
presents us with freedom to animate already existing classes in
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index dd846955f6..6a8948822c 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -28,8 +28,9 @@ SOURCES += \
global/qmalloc.cpp \
global/qnumeric.cpp \
global/qlogging.cpp \
- global/qhooks.cpp \
- global/qversiontagging.cpp
+ global/qhooks.cpp
+
+VERSIONTAGGING_SOURCES = global/qversiontagging.cpp
# qlibraryinfo.cpp includes qconfig.cpp
INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
@@ -63,3 +64,21 @@ journald {
syslog {
DEFINES += QT_USE_SYSLOG
}
+
+gcc:ltcg {
+ versiontagging_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $(INCPATH)
+
+ # Disable LTO, as the symbols disappear somehow under GCC
+ versiontagging_compiler.commands += -fno-lto
+
+ versiontagging_compiler.commands += -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
+ versiontagging_compiler.dependency_type = TYPE_C
+ versiontagging_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ versiontagging_compiler.input = VERSIONTAGGING_SOURCES
+ versiontagging_compiler.variable_out = OBJECTS
+ versiontagging_compiler.name = compiling[versiontagging] ${QMAKE_FILE_IN}
+ silent: versiontagging_compiler.commands = @echo compiling[versiontagging] ${QMAKE_FILE_IN} && $$versiontagging_compiler.commands
+ QMAKE_EXTRA_COMPILERS += versiontagging_compiler
+} else {
+ SOURCES += $$VERSIONTAGGING_SOURCES
+}
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 1ebf37d610..c5424be035 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -748,7 +748,9 @@
# define Q_COMPILER_TEMPLATE_ALIAS
# endif
# if __has_feature(cxx_thread_local)
-# define Q_COMPILER_THREAD_LOCAL
+# if !defined(__FreeBSD__) /* FreeBSD clang fails on __cxa_thread_atexit */
+# define Q_COMPILER_THREAD_LOCAL
+# endif
# endif
# if __has_feature(cxx_user_literals)
# define Q_COMPILER_UDL
@@ -1108,7 +1110,8 @@
# define Q_DECL_NOTHROW Q_DECL_NOEXCEPT
#endif
-#if defined(Q_COMPILER_ALIGNOF) && !defined(Q_ALIGNOF)
+#if defined(Q_COMPILER_ALIGNOF)
+# undef Q_ALIGNOF
# define Q_ALIGNOF(x) alignof(x)
#endif
diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h
index c5ff82c10a..34bb015a2f 100644
--- a/src/corelib/global/qendian.h
+++ b/src/corelib/global/qendian.h
@@ -49,6 +49,11 @@
QT_BEGIN_NAMESPACE
+#ifdef __has_builtin
+# define QT_HAS_BUILTIN(x) __has_builtin(x)
+#else
+# define QT_HAS_BUILTIN(x) 0
+#endif
/*
* ENDIAN FUNCTIONS
@@ -71,18 +76,29 @@ template <typename T> inline void qbswap(const T src, uchar *dest)
// Used to implement a type-safe and alignment-safe copy operation
// If you want to avoid the memcpy, you must write specializations for these functions
-template <typename T> inline void qToUnaligned(const T src, uchar *dest)
+template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, uchar *dest)
{
// Using sizeof(T) inside memcpy function produces internal compiler error with
// MSVC2008/ARM in tst_endian -> use extra indirection to resolve size of T.
const size_t size = sizeof(T);
- memcpy(dest, &src, size);
+#if QT_HAS_BUILTIN(__builtin_memcpy)
+ __builtin_memcpy
+#else
+ memcpy
+#endif
+ (dest, &src, size);
}
-template <typename T> inline T qFromUnaligned(const uchar *src)
+
+template <typename T> Q_ALWAYS_INLINE T qFromUnaligned(const uchar *src)
{
T dest;
const size_t size = sizeof(T);
- memcpy(&dest, src, size);
+#if QT_HAS_BUILTIN(__builtin_memcpy)
+ __builtin_memcpy
+#else
+ memcpy
+#endif
+ (&dest, src, size);
return dest;
}
diff --git a/src/corelib/global/qendian.qdoc b/src/corelib/global/qendian.qdoc
index 63d924211f..3b22dcec87 100644
--- a/src/corelib/global/qendian.qdoc
+++ b/src/corelib/global/qendian.qdoc
@@ -34,6 +34,29 @@
*/
/*!
+ \internal
+ \fn T qFromUnaligned(const uchar *ptr)
+ \since 5.5
+
+ Loads a \c{T} from address \a ptr, which may be misaligned.
+
+ Use of this function avoids the undefined behavior that the C++ standard
+ otherwise attributes to unaligned loads.
+*/
+
+/*!
+ \internal
+ \fn void qToUnaligned(T t, uchar *ptr)
+ \since 4.5
+
+ Stores \a t to address \a ptr, which may be misaligned.
+
+ Use of this function avoids the undefined behavior that the C++ standard
+ otherwise attributes to unaligned stores.
+*/
+
+
+/*!
\fn T qFromBigEndian(const uchar *src)
\since 4.3
\relates <QtEndian>
diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp
index 2ec1714cd2..7b9a3db30d 100644
--- a/src/corelib/global/qhooks.cpp
+++ b/src/corelib/global/qhooks.cpp
@@ -67,7 +67,7 @@ quintptr Q_CORE_EXPORT qtHookData[] = {
// The required sizes and offsets are tested in tests/auto/other/toolsupport.
// When this fails and the change was intentional, adjust the test and
// adjust this value here.
- 14
+ 15
};
Q_STATIC_ASSERT(QHooks::LastHookIndex == sizeof(qtHookData) / sizeof(qtHookData[0]));
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index 10f9068d0a..ccf5851d18 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -66,6 +66,7 @@
NETBSD - NetBSD
OPENBSD - OpenBSD
BSDI - BSD/OS
+ INTERIX - Interix
IRIX - SGI Irix
OSF - HP Tru64 UNIX
SCO - SCO OpenServer 5
@@ -172,6 +173,9 @@
#elif defined(__bsdi__)
# define Q_OS_BSDI
# define Q_OS_BSD4
+#elif defined(__INTERIX)
+# define Q_OS_INTERIX
+# define Q_OS_BSD4
#elif defined(__sgi)
# define Q_OS_IRIX
#elif defined(__osf__)
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index eb9471b502..ab345e9aae 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -144,7 +144,6 @@ win32 {
!nacl:mac: {
SOURCES += io/qsettings_mac.cpp
}
- freebsd: LIBS_PRIVATE += -lutil # qlockfile_unix.cpp requires this
mac {
SOURCES += io/qstorageinfo_mac.cpp
OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 0d9fdb3453..fa919e9f10 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -166,16 +166,15 @@ void QDebug::putUcs4(uint ucs4)
{
maybeQuote('\'');
if (ucs4 < 0x20) {
- stream->ts << hex << "\\x" << ucs4 << reset;
+ stream->ts << "\\x" << hex << ucs4 << reset;
} else if (ucs4 < 0x80) {
stream->ts << char(ucs4);
} else {
- stream->ts << hex << qSetPadChar(QLatin1Char('0'));
if (ucs4 < 0x10000)
- stream->ts << qSetFieldWidth(4) << "\\u";
+ stream->ts << "\\u" << qSetFieldWidth(4);
else
- stream->ts << qSetFieldWidth(8) << "\\U";
- stream->ts << ucs4 << reset;
+ stream->ts << "\\U" << qSetFieldWidth(8);
+ stream->ts << hex << qSetPadChar(QLatin1Char('0')) << ucs4 << reset;
}
maybeQuote('\'');
}
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 76b56f4699..6366c5120c 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -820,7 +820,7 @@ QString QFileInfo::completeBaseName() const
}
/*!
- Returns the complete suffix of the file.
+ Returns the complete suffix (extension) of the file.
The complete suffix consists of all characters in the file after
(but not including) the first '.'.
@@ -839,7 +839,7 @@ QString QFileInfo::completeSuffix() const
}
/*!
- Returns the suffix of the file.
+ Returns the suffix (extension) of the file.
The suffix consists of all characters in the file after (but not
including) the last '.'.
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index 1e22252217..55f4bddd17 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -58,7 +58,7 @@
# include "qfilesystemwatcher_win_p.h"
#elif defined(USE_INOTIFY)
# include "qfilesystemwatcher_inotify_p.h"
-#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(QT_PLATFORM_UIKIT)
+#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) || defined(QT_PLATFORM_UIKIT)
# include "qfilesystemwatcher_kqueue_p.h"
#elif defined(Q_OS_OSX)
# include "qfilesystemwatcher_fsevents_p.h"
@@ -74,7 +74,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject
// there is a chance that inotify may fail on Linux pre-2.6.13 (August
// 2005), so we can't just new inotify directly.
return QInotifyFileSystemWatcherEngine::create(parent);
-#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(QT_PLATFORM_UIKIT)
+#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) || defined(QT_PLATFORM_UIKIT)
return QKqueueFileSystemWatcherEngine::create(parent);
#elif defined(Q_OS_OSX)
return QFseventsFileSystemWatcherEngine::create(parent);
diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp
index 264973d556..4f6c83ebcf 100644
--- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp
+++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp
@@ -172,7 +172,6 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
QStringList *files,
QStringList *directories)
{
- bool isEmpty;
QStringList p = paths;
if (pathToID.isEmpty())
return p;
@@ -193,7 +192,6 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
else
files->removeAll(path);
}
- isEmpty = pathToID.isEmpty();
return p;
}
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index ba59ea8341..79141d1e8f 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -71,14 +71,12 @@
#elif defined(Q_OS_HAIKU)
# include <kernel/OS.h>
#elif defined(Q_OS_BSD4) && !defined(QT_PLATFORM_UIKIT)
+# if !defined(Q_OS_NETBSD)
# include <sys/user.h>
-# if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
+# endif
# include <sys/cdefs.h>
# include <sys/param.h>
# include <sys/sysctl.h>
-# else
-# include <libutil.h>
-# endif
#endif
QT_BEGIN_NAMESPACE
@@ -286,30 +284,33 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
return QString();
return QFile::decodeName(info.name);
#elif defined(Q_OS_BSD4) && !defined(QT_PLATFORM_UIKIT)
-# if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
- int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
- size_t len = 0;
- if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0)
- return QString();
- kinfo_proc *proc = static_cast<kinfo_proc *>(malloc(len));
+# if defined(Q_OS_NETBSD)
+ struct kinfo_proc2 kp;
+ int mib[6] = { CTL_KERN, KERN_PROC2, KERN_PROC_PID, (int)pid, sizeof(struct kinfo_proc2), 1 };
+# elif defined(Q_OS_OPENBSD)
+ struct kinfo_proc kp;
+ int mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid, sizeof(struct kinfo_proc), 1 };
# else
- kinfo_proc *proc = kinfo_getproc(pid);
+ struct kinfo_proc kp;
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid };
# endif
- if (!proc)
+ size_t len = sizeof(kp);
+ u_int mib_len = sizeof(mib)/sizeof(u_int);
+
+ if (sysctl(mib, mib_len, &kp, &len, NULL, 0) < 0)
return QString();
-# if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
- if (sysctl(mib, 4, proc, &len, NULL, 0) < 0) {
- free(proc);
+
+# if defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD)
+ if (kp.p_pid != pid)
return QString();
- }
- if (proc->ki_pid != pid) {
- free(proc);
+ QString name = QFile::decodeName(kp.p_comm);
+# else
+ if (kp.ki_pid != pid)
return QString();
- }
+ QString name = QFile::decodeName(kp.ki_comm);
# endif
- QString name = QFile::decodeName(proc->ki_comm);
- free(proc);
return name;
+
#else
Q_UNUSED(pid);
return QString();
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index ba4a091965..baaff8da17 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -143,9 +143,11 @@ bool QLockFilePrivate::isApparentlyStale() const
if (!procHandle)
return true;
// We got a handle but check if process is still alive
- DWORD dwR = ::WaitForSingleObject(procHandle, 0);
+ DWORD exitCode = 0;
+ if (!::GetExitCodeProcess(procHandle, &exitCode))
+ exitCode = 0;
::CloseHandle(procHandle);
- if (dwR == WAIT_TIMEOUT)
+ if (exitCode != STILL_ACTIVE)
return true;
const QString processName = processNameByPid(pid);
if (!processName.isEmpty() && processName != appname)
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 227241b208..ebafd6b524 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -2087,10 +2087,7 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM
return;
}
if (program.isEmpty()) {
- Q_D(QProcess);
- d->processError = QProcess::FailedToStart;
- setErrorString(tr("No program defined"));
- emit error(d->processError);
+ d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
return;
}
@@ -2117,10 +2114,7 @@ void QProcess::start(OpenMode mode)
return;
}
if (d->program.isEmpty()) {
- Q_D(QProcess);
- d->processError = QProcess::FailedToStart;
- setErrorString(tr("No program defined"));
- emit error(d->processError);
+ d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
return;
}
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 3a9f74bf59..0daf041954 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -84,7 +84,7 @@
# if !defined(ST_RDONLY)
# define ST_RDONLY MNT_RDONLY
# endif
-# if !defined(_STATFS_F_FLAGS)
+# if !defined(_STATFS_F_FLAGS) && !defined(Q_OS_NETBSD)
# define _STATFS_F_FLAGS 1
# endif
#elif defined(Q_OS_ANDROID)
diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp
index 64c9692e23..3ab2c70c75 100644
--- a/src/corelib/io/qwindowspipewriter.cpp
+++ b/src/corelib/io/qwindowspipewriter.cpp
@@ -205,6 +205,8 @@ bool QWindowsPipeWriter::write(const QByteArray &ba)
void QWindowsPipeWriter::stop()
{
stopped = true;
+ bytesWrittenPending = false;
+ pendingBytesWrittenValue = 0;
if (writeSequenceStarted) {
if (!CancelIoEx(handle, &overlapped)) {
const DWORD dwError = GetLastError();
diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h
index d16b6e5b00..f2fcb767d5 100644
--- a/src/corelib/json/qjson_p.h
+++ b/src/corelib/json/qjson_p.h
@@ -410,7 +410,7 @@ public:
// pack with itself, we'll discard the high part anyway
chunk = _mm_packus_epi16(chunk, chunk);
// unaligned 64-bit store
- qUnalignedStore(l + i, _mm_cvtsi128_si64(chunk));
+ qToUnaligned(_mm_cvtsi128_si64(chunk), l + i);
i += 8;
}
# endif
@@ -684,6 +684,8 @@ public:
bool operator >=(const Entry &other) const;
};
+inline bool operator!=(const Entry &lhs, const Entry &rhs) { return !(lhs == rhs); }
+
inline bool Entry::operator >=(const QString &key) const
{
if (value.latinKey)
diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp
index b5b6f36bc6..fb651f0f24 100644
--- a/src/corelib/json/qjsonobject.cpp
+++ b/src/corelib/json/qjsonobject.cpp
@@ -599,8 +599,8 @@ bool QJsonObject::operator==(const QJsonObject &other) const
for (uint i = 0; i < o->length; ++i) {
QJsonPrivate::Entry *e = o->entryAt(i);
- QJsonValue v(d, o, e->value);
- if (other.value(e->key()) != v)
+ QJsonPrivate::Entry *oe = other.o->entryAt(i);
+ if (*e != *oe || QJsonValue(d, o, e->value) != QJsonValue(other.d, other.o, oe->value))
return false;
}
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index b21f59ae35..718dfa43b3 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -275,25 +275,11 @@ QJsonValue::QJsonValue(const QJsonValue &other)
*/
QJsonValue &QJsonValue::operator =(const QJsonValue &other)
{
- if (t == String && stringData && !stringData->ref.deref())
- free(stringData);
-
- t = other.t;
- dbl = other.dbl;
-
- if (d != other.d) {
-
- if (d && !d->ref.deref())
- delete d;
- d = other.d;
- if (d)
- d->ref.ref();
-
- }
-
- if (t == String && stringData)
- stringData->ref.ref();
-
+ QJsonValue copy(other);
+ // swap(copy);
+ qSwap(dbl, copy.dbl);
+ qSwap(d, copy.d);
+ qSwap(t, copy.t);
return *this;
}
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index 93af957d95..2042964427 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -41,16 +41,6 @@
#include "qcore_unix_p.h"
#include "qelapsedtimer.h"
-#ifdef Q_OS_NACL
-#elif !defined (Q_OS_VXWORKS)
-# if !defined(Q_OS_HPUX) || defined(__ia64)
-# include <sys/select.h>
-# endif
-# include <sys/time.h>
-#else
-# include <selectLib.h>
-#endif
-
#include <stdlib.h>
#ifdef Q_OS_MAC
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index b08571223f..6ed316254b 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -65,6 +65,16 @@
#include <sys/stat.h>
#include <unistd.h>
+#ifdef Q_OS_NACL
+#elif !defined (Q_OS_VXWORKS)
+# if !defined(Q_OS_HPUX) || defined(__ia64)
+# include <sys/select.h>
+# endif
+# include <sys/time.h>
+#else
+# include <selectLib.h>
+#endif
+
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 9b421d6a78..ffb50ddac3 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4699,7 +4699,7 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
- if (type & Qt::UniqueConnection) {
+ if (type & Qt::UniqueConnection && slot) {
QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
if (connectionLists && connectionLists->count() > signal_index) {
const QObjectPrivate::Connection *c2 =
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 87d006bdc6..3cec9802dc 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -302,7 +302,6 @@ public:
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
Qt::ConnectionType type = Qt::AutoConnection)
{
-#if defined (Q_COMPILER_VARIADIC_TEMPLATES)
typedef QtPrivate::FunctionPointer<Func1> SignalType;
const int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<Func2 , typename SignalType::Arguments>::Value;
@@ -310,28 +309,6 @@ public:
"Signal and slot arguments are not compatible.");
const int SlotArgumentCount = (FunctorArgumentCount >= 0) ? FunctorArgumentCount : 0;
typedef typename QtPrivate::FunctorReturnType<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value>::Value SlotReturnType;
-#else
- // Without variadic template, we don't detect the best overload of operator(). We just
- // assume there is only one simple operator() and connect to &Func2::operator()
-
- /* If you get an error such as:
- couldn't deduce template parameter 'Func2Operator'
- or
- cannot resolve address of overloaded function
- It means the functor does not have a single operator().
- Functors with overloaded or templated operator() are only supported if the compiler supports
- C++11 variadic templates
- */
- typedef QtPrivate::FunctionPointer<decltype(&Func2::operator())> SlotType ;
- typedef QtPrivate::FunctionPointer<Func1> SignalType;
- typedef typename SlotType::ReturnType SlotReturnType;
- const int SlotArgumentCount = SlotType::ArgumentCount;
-
- Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= SlotArgumentCount,
- "The slot requires more arguments than the signal provides.");
- Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
- "Signal and slot arguments are not compatible.");
-#endif
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
@@ -446,8 +423,7 @@ protected:
QScopedPointer<QObjectData> d_ptr;
static const QMetaObject staticQtMetaObject;
- friend inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT
- { return &staticQtMetaObject; }
+ friend inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT;
friend struct QMetaObject;
friend struct QMetaObjectPrivate;
@@ -478,6 +454,9 @@ inline QMetaObject::Connection QObject::connect(const QObject *asender, const ch
const char *amember, Qt::ConnectionType atype) const
{ return connect(asender, asignal, this, amember, atype); }
+inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT
+{ return &QObject::staticQtMetaObject; }
+
#ifndef QT_NO_USERDATA
class Q_CORE_EXPORT QObjectUserData {
public:
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index b4091a4f1c..d7ae63a98c 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -62,34 +62,6 @@ namespace QtPrivate {
If one of the type is not declared, the function return 0 and the signal
cannot be used in queued connection.
*/
-#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template <typename ArgList> struct TypesAreDeclaredMetaType { enum { Value = false }; };
- template <> struct TypesAreDeclaredMetaType<void> { enum { Value = true }; };
- template <typename Arg, typename Tail> struct TypesAreDeclaredMetaType<List<Arg, Tail> > { enum { Value = QMetaTypeId2<Arg>::Defined && TypesAreDeclaredMetaType<Tail>::Value }; };
-
- template <typename ArgList, bool Declared = TypesAreDeclaredMetaType<ArgList>::Value > struct ConnectionTypes
- { static const int *types() { return 0; } };
- template <> struct ConnectionTypes<void, true>
- { static const int *types() { static const int t[1] = { 0 }; return t; } };
- template <typename Arg1> struct ConnectionTypes<List<Arg1, void>, true>
- { static const int *types() { static const int t[2] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), 0 }; return t; } };
- template <typename Arg1, typename Arg2> struct ConnectionTypes<List<Arg1, List<Arg2, void> >, true>
- { static const int *types() { static const int t[3] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg2>::qt_metatype_id(), 0 }; return t; } };
- template <typename Arg1, typename Arg2, typename Arg3> struct ConnectionTypes<List<Arg1, List<Arg2, List<Arg3, void> > >, true>
- { static const int *types() { static const int t[4] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg2>::qt_metatype_id(),
- QtPrivate::QMetaTypeIdHelper<Arg3>::qt_metatype_id(), 0 }; return t; } };
- template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct ConnectionTypes<List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > >, true>
- { static const int *types() { static const int t[5] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg2>::qt_metatype_id(),
- QtPrivate::QMetaTypeIdHelper<Arg3>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg4>::qt_metatype_id(), 0 }; return t; } };
- template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct ConnectionTypes<List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > >, true>
- { static const int *types() { static const int t[6] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg2>::qt_metatype_id(),
- QtPrivate::QMetaTypeIdHelper<Arg3>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg4>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg5>::qt_metatype_id(), 0 }; return t; } };
- template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
- struct ConnectionTypes<List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > >, true>
- { static const int *types() { static const int t[7] = { QtPrivate::QMetaTypeIdHelper<Arg1>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg2>::qt_metatype_id(),
- QtPrivate::QMetaTypeIdHelper<Arg3>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg4>::qt_metatype_id(), QtPrivate::QMetaTypeIdHelper<Arg5>::qt_metatype_id(),
- QtPrivate::QMetaTypeIdHelper<Arg6>::qt_metatype_id(), 0 }; return t; } };
-#else
template <typename ArgList> struct TypesAreDeclaredMetaType { enum { Value = false }; };
template <> struct TypesAreDeclaredMetaType<List<>> { enum { Value = true }; };
template <typename Arg, typename... Tail> struct TypesAreDeclaredMetaType<List<Arg, Tail...> >
@@ -101,7 +73,6 @@ namespace QtPrivate {
{ static const int *types() { return Q_NULLPTR; } };
template <typename... Args> struct ConnectionTypes<List<Args...>, true>
{ static const int *types() { static const int t[sizeof...(Args) + 1] = { (QtPrivate::QMetaTypeIdHelper<Args>::qt_metatype_id())..., 0 }; return t; } };
-#endif
// internal base class (interface) containing functions required to call a slot managed by a pointer to function.
class QSlotObjectBase {
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index 6ef83a6eb5..5eae70ecc5 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -65,11 +65,6 @@ namespace QtPrivate {
List_Left<L,N> take a list and a number as a parameter and returns (via the Value typedef,
the list composed of the first N element of the list
*/
-#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template <typename Head, typename Tail> struct List { typedef Head Car; typedef Tail Cdr; };
- template <typename L, int N> struct List_Left { typedef List<typename L::Car, typename List_Left<typename L::Cdr, N - 1>::Value > Value; };
- template <typename L> struct List_Left<L,0> { typedef void Value; };
-#else
// With variadic template, lists are represented using a variadic template argument instead of the lisp way
template <typename...> struct List {};
template <typename Head, typename... Tail> struct List<Head, Tail...> { typedef Head Car; typedef List<Tail...> Cdr; };
@@ -79,7 +74,6 @@ namespace QtPrivate {
typedef typename List_Append<List<typename L::Car>,typename List_Left<typename L::Cdr, N - 1>::Value>::Value Value;
};
template <typename L> struct List_Left<L, 0> { typedef List<> Value; };
-#endif
// List_Select<L,N> returns (via typedef Value) the Nth element of the list L
template <typename L, int N> struct List_Select { typedef typename List_Select<typename L::Cdr, N - 1>::Value Value; };
template <typename L> struct List_Select<L,0> { typedef typename L::Car Value; };
@@ -100,13 +94,11 @@ namespace QtPrivate {
if (container.data)
*reinterpret_cast<U*>(container.data) = value;
}
-#ifdef Q_COMPILER_RVALUE_REFS
template<typename T, typename U>
void operator,(T &&value, const ApplyReturnValue<U> &container) {
if (container.data)
*reinterpret_cast<U*>(container.data) = value;
}
-#endif
template<typename T>
void operator,(T, const ApplyReturnValue<void> &) {}
@@ -127,364 +119,6 @@ namespace QtPrivate {
The Functor<Func,N> struct is the helper to call a functor of N argument.
its call function is the same as the FunctionPointer::call function.
*/
-#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
- //Pointers to member functions
- template<class Obj, typename Ret> struct FunctionPointer<Ret (Obj::*) ()>
- {
- typedef Obj Object;
- typedef void Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) ();
- enum {ArgumentCount = 0, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
- };
- template<class Obj, typename Ret, typename Arg1> struct FunctionPointer<Ret (Obj::*) (Arg1)>
- {
- typedef Obj Object;
- typedef List<Arg1, void> Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1);
- enum {ArgumentCount = 1, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, void> > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2);
- enum {ArgumentCount = 2, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3);
- enum {ArgumentCount = 3, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4);
- enum {ArgumentCount = 4, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
- enum {ArgumentCount = 5, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
- struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
- enum {ArgumentCount = 6, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
- }
- };
-
- //Pointers to const member functions
- template<class Obj, typename Ret> struct FunctionPointer<Ret (Obj::*) () const>
- {
- typedef Obj Object;
- typedef void Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) () const;
- enum {ArgumentCount = 0, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
- };
- template<class Obj, typename Ret, typename Arg1> struct FunctionPointer<Ret (Obj::*) (Arg1) const>
- {
- typedef Obj Object;
- typedef List<Arg1, void> Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1) const;
- enum {ArgumentCount = 1, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2) const>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, void> > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2) const;
- enum {ArgumentCount = 2, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3) const>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3) const;
- enum {ArgumentCount = 3, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4) const>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4) const;
- enum {ArgumentCount = 4, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5) const>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5) const;
- enum {ArgumentCount = 5, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
- struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const;
- enum {ArgumentCount = 6, IsPointerToMemberFunction = true};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
- }
- };
-
- //Static functions
- template<typename Ret> struct FunctionPointer<Ret (*) ()>
- {
- typedef void Arguments;
- typedef Ret (*Function) ();
- typedef Ret ReturnType;
- enum {ArgumentCount = 0, IsPointerToMemberFunction = false};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
- };
- template<typename Ret, typename Arg1> struct FunctionPointer<Ret (*) (Arg1)>
- {
- typedef List<Arg1, void> Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1);
- enum {ArgumentCount = 1, IsPointerToMemberFunction = false};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg)
- { f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]); }
- };
- template<typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (*) (Arg1, Arg2)>
- {
- typedef List<Arg1, List<Arg2, void> > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2);
- enum {ArgumentCount = 2, IsPointerToMemberFunction = false};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]); }
- };
- template<typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3)>
- {
- typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2, Arg3);
- enum {ArgumentCount = 3, IsPointerToMemberFunction = false};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4)>
- {
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4);
- enum {ArgumentCount = 4, IsPointerToMemberFunction = false};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4, Arg5)>
- {
- typedef List<Arg1, List<Arg2, List<Arg3,
- List<Arg4, List<Arg5, void > > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
- enum {ArgumentCount = 5, IsPointerToMemberFunction = false};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
- {
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
- enum {ArgumentCount = 6, IsPointerToMemberFunction = false};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
- }
- };
-
- //Functors
- template<typename F, int N> struct Functor;
- template<typename Function> struct Functor<Function, 0>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
- };
- template<typename Function> struct Functor<Function, 1>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 2>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 3>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 4>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 5>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 6>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
- }
- };
-#else
template <int...> struct IndexesList {};
template <typename IndexList, int Right> struct IndexesAppend;
template <int... Left, int Right> struct IndexesAppend<IndexesList<Left...>, Right>
@@ -558,7 +192,6 @@ namespace QtPrivate {
FunctorCall<typename Indexes<N>::Value, SignalArgs, R, Function>::call(f, arg);
}
};
-#endif
/*
Logic that check if the arguments of the slot matches the argument of the signal.
@@ -578,16 +211,6 @@ namespace QtPrivate {
template<typename A> struct AreArgumentsCompatible<A, void> { enum { value = true }; };
template<> struct AreArgumentsCompatible<void, void> { enum { value = true }; };
-#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
- template <> struct CheckCompatibleArguments<void, void> { enum { value = true }; };
- template <typename List1> struct CheckCompatibleArguments<List1, void> { enum { value = true }; };
- template <typename Arg1, typename Arg2, typename Tail1, typename Tail2> struct CheckCompatibleArguments<List<Arg1, Tail1>, List<Arg2, Tail2> >
- {
- enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value
- && CheckCompatibleArguments<Tail1, Tail2>::value };
- };
-#else
template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
template <> struct CheckCompatibleArguments<List<>, List<>> { enum { value = true }; };
template <typename List1> struct CheckCompatibleArguments<List1, List<>> { enum { value = true }; };
@@ -597,9 +220,7 @@ namespace QtPrivate {
enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value
&& CheckCompatibleArguments<List<Tail1...>, List<Tail2...>>::value };
};
-#endif
-#if defined(Q_COMPILER_VARIADIC_TEMPLATES)
/*
Find the maximum number of arguments a functor object can take and be still compatible with
the arguments from the signal.
@@ -631,8 +252,6 @@ namespace QtPrivate {
template <typename D> static D dummy();
typedef decltype(dummy<Functor>().operator()((dummy<ArgList>())...)) Value;
};
-#endif
-
}
QT_END_NAMESPACE
diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp
index 0db3407b7b..8461bf7130 100644
--- a/src/corelib/mimetypes/qmimemagicrule.cpp
+++ b/src/corelib/mimetypes/qmimemagicrule.cpp
@@ -48,7 +48,6 @@
#include <QtCore/QList>
#include <QtCore/QDebug>
#include <qendian.h>
-#include <private/qsimd_p.h> // for qUnalignedLoad
QT_BEGIN_NAMESPACE
@@ -164,7 +163,7 @@ bool QMimeMagicRule::matchNumber(const QByteArray &data) const
const char *p = data.constData() + m_startPos;
const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), m_endPos + 1);
for ( ; p <= e; ++p) {
- if ((qUnalignedLoad<T>(p) & mask) == (value & mask))
+ if ((qFromUnaligned<T>(reinterpret_cast<const uchar *>(p)) & mask) == (value & mask))
return true;
}
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
index 25444ffff6..17072f44d4 100644
--- a/src/corelib/thread/qmutex_linux.cpp
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -57,7 +57,7 @@
#endif
#ifndef FUTEX_PRIVATE_FLAG
-# define FUTEX_PRIVATE_FLAG 128
+# define FUTEX_PRIVATE_FLAG 0
#endif
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index 36f1997a6c..55af7256be 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -87,29 +88,20 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
if (!(options & RawData))
headerSize += (alignment - Q_ALIGNOF(QArrayData));
- // Allocate additional space if array is growing
- if (options & Grow) {
-
- // Guard against integer overflow when multiplying.
- if (capacity > std::numeric_limits<size_t>::max() / objectSize)
- return 0;
-
- size_t alloc;
- if (mul_overflow(objectSize, capacity, &alloc))
- return 0;
-
- // Make sure qAllocMore won't overflow qAllocMore.
- if (headerSize > size_t(MaxAllocSize) || alloc > size_t(MaxAllocSize) - headerSize)
- return 0;
-
- capacity = qAllocMore(int(alloc), int(headerSize)) / int(objectSize);
- }
+ if (headerSize > size_t(MaxAllocSize))
+ return 0;
+ // Calculate the byte size
+ // allocSize = objectSize * capacity + headerSize, but checked for overflow
+ // plus padded to grow in size
size_t allocSize;
- if (mul_overflow(objectSize, capacity, &allocSize))
- return 0;
- if (add_overflow(allocSize, headerSize, &allocSize))
- return 0;
+ if (options & Grow) {
+ auto r = qCalculateGrowingBlockSize(capacity, objectSize, headerSize);
+ capacity = r.elementCount;
+ allocSize = r.size;
+ } else {
+ allocSize = qCalculateBlockSize(capacity, objectSize, headerSize);
+ }
QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
if (header) {
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
index 446e09b1c0..12e4687b3c 100644
--- a/src/corelib/tools/qbitarray.cpp
+++ b/src/corelib/tools/qbitarray.cpp
@@ -42,6 +42,7 @@
#include <qalgorithms.h>
#include <qdatastream.h>
#include <qdebug.h>
+#include <qendian.h>
#include <string.h>
QT_BEGIN_NAMESPACE
@@ -169,25 +170,6 @@ QBitArray::QBitArray(int size, bool value)
Same as size().
*/
-template <typename T> T qUnalignedLoad(const uchar *ptr)
-{
- /*
- * Testing with different compilers shows that they all optimize the memcpy
- * call away and replace with direct loads whenever possible. On x86 and PPC,
- * GCC does direct unaligned loads; on MIPS, it generates a pair of load-left
- * and load-right instructions. ICC and Clang do the same on x86. This is both
- * 32- and 64-bit.
- *
- * On ARM cores without unaligned loads, the compiler leaves a call to
- * memcpy.
- */
-
- T u;
- memcpy(&u, ptr, sizeof(u));
- return u;
-}
-
-
/*!
If \a on is true, this function returns the number of
1-bits stored in the bit array; otherwise the number
@@ -203,17 +185,17 @@ int QBitArray::count(bool on) const
const quint8 *const end = reinterpret_cast<const quint8 *>(d.end());
while (bits + 7 <= end) {
- quint64 v = qUnalignedLoad<quint64>(bits);
+ quint64 v = qFromUnaligned<quint64>(bits);
bits += 8;
numBits += int(qPopulationCount(v));
}
if (bits + 3 <= end) {
- quint32 v = qUnalignedLoad<quint32>(bits);
+ quint32 v = qFromUnaligned<quint32>(bits);
bits += 4;
numBits += int(qPopulationCount(v));
}
if (bits + 1 < end) {
- quint16 v = qUnalignedLoad<quint16>(bits);
+ quint16 v = qFromUnaligned<quint16>(bits);
bits += 2;
numBits += int(qPopulationCount(v));
}
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index a256b44b1f..266c2e9b57 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -46,6 +46,7 @@
#include "qlocale.h"
#include "qlocale_p.h"
#include "qlocale_tools_p.h"
+#include "private/qnumeric_p.h"
#include "qstringalgorithms_p.h"
#include "qscopedpointer.h"
#include "qbytearray_p.h"
@@ -128,17 +129,104 @@ int qFindByteArray(
const char *haystack0, int haystackLen, int from,
const char *needle0, int needleLen);
+/*
+ * This pair of functions is declared in qtools_p.h and is used by the Qt
+ * containers to allocate memory and grow the memory block during append
+ * operations.
+ *
+ * They take size_t parameters and return size_t so they will change sizes
+ * according to the pointer width. However, knowing Qt containers store the
+ * container size and element indexes in ints, these functions never return a
+ * size larger than INT_MAX. This is done by casting the element count and
+ * memory block size to int in several comparisons: the check for negative is
+ * very fast on most platforms as the code only needs to check the sign bit.
+ *
+ * These functions return SIZE_MAX on overflow, which can be passed to malloc()
+ * and will surely cause a NULL return (there's no way you can allocate a
+ * memory block the size of your entire VM space).
+ */
+
+/*!
+ \internal
+ \since 5.7
-int qAllocMore(int alloc, int extra) Q_DECL_NOTHROW
+ Returns the memory block size for a container containing \a elementCount
+ elements, each of \a elementSize bytes, plus a header of \a headerSize
+ bytes. That is, this function returns \c
+ {elementCount * elementSize + headerSize}
+
+ but unlike the simple calculation, it checks for overflows during the
+ multiplication and the addition.
+
+ Both \a elementCount and \a headerSize can be zero, but \a elementSize
+ cannot.
+
+ This function returns SIZE_MAX (~0) on overflow or if the memory block size
+ would not fit an int.
+*/
+size_t qCalculateBlockSize(size_t elementCount, size_t elementSize, size_t headerSize) Q_DECL_NOTHROW
{
- Q_ASSERT(alloc >= 0 && extra >= 0 && extra <= MaxAllocSize);
- Q_ASSERT_X(alloc <= MaxAllocSize - extra, "qAllocMore", "Requested size is too large!");
+ unsigned count = unsigned(elementCount);
+ unsigned size = unsigned(elementSize);
+ unsigned header = unsigned(headerSize);
+ Q_ASSERT(elementSize);
+ Q_ASSERT(size == elementSize);
+ Q_ASSERT(header == headerSize);
+
+ if (Q_UNLIKELY(count != elementCount))
+ return std::numeric_limits<size_t>::max();
+
+ unsigned bytes;
+ if (Q_UNLIKELY(mul_overflow(size, count, &bytes)) ||
+ Q_UNLIKELY(add_overflow(bytes, header, &bytes)))
+ return std::numeric_limits<size_t>::max();
+ if (Q_UNLIKELY(int(bytes) < 0)) // catches bytes >= 2GB
+ return std::numeric_limits<size_t>::max();
+
+ return bytes;
+}
+
+/*!
+ \internal
+ \since 5.7
- unsigned nalloc = qNextPowerOfTwo(alloc + extra);
+ Returns the memory block size and the number of elements that will fit in
+ that block for a container containing \a elementCount elements, each of \a
+ elementSize bytes, plus a header of \a headerSize bytes. This function
+ assumes the container will grow and pre-allocates a growth factor.
- Q_ASSERT(nalloc > unsigned(alloc + extra));
+ Both \a elementCount and \a headerSize can be zero, but \a elementSize
+ cannot.
+
+ This function returns SIZE_MAX (~0) on overflow or if the memory block size
+ would not fit an int.
+
+ \note The memory block may contain up to \a elementSize - 1 bytes more than
+ needed.
+*/
+CalculateGrowingBlockSizeResult
+qCalculateGrowingBlockSize(size_t elementCount, size_t elementSize, size_t headerSize) Q_DECL_NOTHROW
+{
+ CalculateGrowingBlockSizeResult result = {
+ std::numeric_limits<size_t>::max(),std::numeric_limits<size_t>::max()
+ };
+
+ unsigned bytes = unsigned(qCalculateBlockSize(elementCount, elementSize, headerSize));
+ if (int(bytes) < 0) // catches std::numeric_limits<size_t>::max()
+ return result;
+
+ unsigned morebytes = qNextPowerOfTwo(bytes);
+ if (Q_UNLIKELY(int(morebytes) < 0)) {
+ // catches morebytes == 2GB
+ // grow by half the difference between bytes and morebytes
+ bytes += (morebytes - bytes) / 2;
+ } else {
+ bytes = morebytes;
+ }
- return nalloc - extra;
+ result.elementCount = (bytes - unsigned(headerSize)) / unsigned(elementSize);
+ result.size = bytes;
+ return result;
}
/*****************************************************************************
@@ -1618,12 +1706,16 @@ void QByteArray::reallocData(uint alloc, Data::AllocationOptions options)
Data::deallocate(d);
d = x;
} else {
+ size_t blockSize;
if (options & Data::Grow) {
- if (alloc > MaxByteArraySize)
- qBadAlloc();
- alloc = qAllocMore(alloc, sizeof(Data));
+ auto r = qCalculateGrowingBlockSize(alloc, sizeof(QChar), sizeof(Data));
+ blockSize = r.size;
+ alloc = uint(r.elementCount);
+ } else {
+ blockSize = qCalculateBlockSize(alloc, sizeof(QChar), sizeof(Data));
}
- Data *x = static_cast<Data *>(::realloc(d, sizeof(Data) + alloc));
+
+ Data *x = static_cast<Data *>(::realloc(d, blockSize));
Q_CHECK_PTR(x);
x->alloc = alloc;
x->capacityReserved = (options & Data::CapacityReserved) ? 1 : 0;
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index 3cb3606013..08f89d2f02 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -95,9 +95,29 @@ static SHA3Final * const sha3Final = Final;
available on all platforms (MSVC 2008, for example), we #define them to the
Qt equivalents.
*/
+
+#ifdef uint64_t
+#undef uint64_t
+#endif
+
#define uint64_t QT_PREPEND_NAMESPACE(quint64)
+
+#ifdef uint32_t
+#undef uint32_t
+#endif
+
#define uint32_t QT_PREPEND_NAMESPACE(quint32)
+
+#ifdef uint8_t
+#undef uint8_t
+#endif
+
#define uint8_t QT_PREPEND_NAMESPACE(quint8)
+
+#ifdef int_least16_t
+#undef int_least16_t
+#endif
+
#define int_least16_t QT_PREPEND_NAMESPACE(qint16)
// Header from rfc6234 with 1 modification:
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 02afacb861..2ebf7c7977 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -2158,7 +2158,7 @@ static int qt_timezone()
// number of seconds west of UTC.
// - It also takes DST into account, so we need to adjust it to always
// get the Standard Time offset.
- return -t.tm_gmtoff + (t.tm_isdst ? SECS_PER_HOUR : 0L);
+ return -t.tm_gmtoff + (t.tm_isdst ? (long)SECS_PER_HOUR : 0L);
#elif defined(Q_OS_INTEGRITY)
return 0;
#else
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index cc8c08d5b1..9c9009d636 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -708,17 +708,18 @@ int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionInde
}
const int sectionmaxsize = sectionMaxSize(sectionIndex);
- QString sectiontext = text.mid(index, sectionmaxsize);
- int sectiontextSize = sectiontext.size();
+ QStringRef sectionTextRef = text.midRef(index, sectionmaxsize);
+ int sectiontextSize = sectionTextRef.size();
QDTPDEBUG << "sectionValue for" << sn.name()
- << "with text" << text << "and st" << sectiontext
+ << "with text" << text << "and st" << sectionTextRef
<< text.midRef(index, sectionmaxsize)
<< index;
int used = 0;
switch (sn.type) {
case AmPmSection: {
+ QString sectiontext = sectionTextRef.toString();
const int ampm = findAmPm(sectiontext, sectionIndex, &used);
switch (ampm) {
case AM: // sectiontext == AM
@@ -750,6 +751,7 @@ int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionInde
case DayOfWeekSectionShort:
case DayOfWeekSectionLong:
if (sn.count >= 3) {
+ QString sectiontext = sectionTextRef.toString();
if (sn.type == MonthSection) {
int min = 1;
const QDate minDate = getMinimum().date();
@@ -788,7 +790,7 @@ int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionInde
int last = -1;
used = -1;
- QString digitsStr(sectiontext);
+ QStringRef digitsStr = sectionTextRef;
for (int i = 0; i < sectiontextSize; ++i) {
if (digitsStr.at(i).isSpace()) {
sectiontextSize = i;
@@ -809,7 +811,7 @@ int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionInde
}
}
if (ok && tmp <= absMax) {
- QDTPDEBUG << sectiontext.leftRef(digits) << tmp << digits;
+ QDTPDEBUG << sectionTextRef.left(digits) << tmp << digits;
last = tmp;
used = digits;
break;
@@ -817,13 +819,13 @@ int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionInde
}
if (last == -1) {
- QChar first(sectiontext.at(0));
+ QChar first(sectionTextRef.at(0));
if (separators.at(sectionIndex + 1).startsWith(first)) {
used = 0;
state = Intermediate;
} else {
state = Invalid;
- QDTPDEBUG << "invalid because" << sectiontext << "can't become a uint" << last << ok;
+ QDTPDEBUG << "invalid because" << sectionTextRef << "can't become a uint" << last << ok;
}
} else {
num += last;
@@ -1565,7 +1567,7 @@ QString QDateTimeParser::SectionNode::format() const
number that is within min and max.
*/
-bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int index,
+bool QDateTimeParser::potentialValue(const QStringRef &str, int min, int max, int index,
const QDateTime &currentValue, int insert) const
{
if (str.isEmpty()) {
@@ -1592,8 +1594,7 @@ bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int i
if (potentialValue(str + QLatin1Char('0' + j), min, max, index, currentValue, insert)) {
return true;
} else if (insert >= 0) {
- QString tmp = str;
- tmp.insert(insert, QLatin1Char('0' + j));
+ const QString tmp = str.left(insert) + QLatin1Char('0' + j) + str.mid(insert);
if (potentialValue(tmp, min, max, index, currentValue, insert))
return true;
}
@@ -1603,7 +1604,7 @@ bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int i
return false;
}
-bool QDateTimeParser::skipToNextSection(int index, const QDateTime &current, const QString &text) const
+bool QDateTimeParser::skipToNextSection(int index, const QDateTime &current, const QStringRef &text) const
{
Q_ASSERT(current >= getMinimum() && current <= getMaximum());
diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h
index 9689d88616..01a2f20802 100644
--- a/src/corelib/tools/qdatetimeparser_p.h
+++ b/src/corelib/tools/qdatetimeparser_p.h
@@ -214,9 +214,19 @@ public:
QString *dayName = 0, int *used = 0) const;
#endif
AmPmFinder findAmPm(QString &str, int index, int *used = 0) const;
- bool potentialValue(const QString &str, int min, int max, int index,
+ bool potentialValue(const QStringRef &str, int min, int max, int index,
const QDateTime &currentValue, int insert) const;
- bool skipToNextSection(int section, const QDateTime &current, const QString &sectionText) const;
+ bool potentialValue(const QString &str, int min, int max, int index,
+ const QDateTime &currentValue, int insert) const
+ {
+ return potentialValue(QStringRef(&str), min, max, index, currentValue, insert);
+ }
+
+ bool skipToNextSection(int section, const QDateTime &current, const QStringRef &sectionText) const;
+ bool skipToNextSection(int section, const QDateTime &current, const QString &sectionText) const
+ {
+ return skipToNextSection(section, current, QStringRef(&sectionText));
+ }
QString stateName(State s) const;
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 2f0886edce..593a87e65d 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -58,6 +58,7 @@
#include <qbytearray.h>
#include <qdatetime.h>
#include <qbasicatomic.h>
+#include <qendian.h>
#include <private/qsimd_p.h>
#ifndef QT_BOOTSTRAPPED
@@ -112,24 +113,24 @@ static uint crc32(const Char *ptr, size_t len, uint h)
p += 8;
for ( ; p <= e; p += 8)
- h2 = _mm_crc32_u64(h2, qUnalignedLoad<qlonglong>(p - 8));
+ h2 = _mm_crc32_u64(h2, qFromUnaligned<qlonglong>(p - 8));
h = h2;
p -= 8;
len = e - p;
if (len & 4) {
- h = _mm_crc32_u32(h, qUnalignedLoad<uint>(p));
+ h = _mm_crc32_u32(h, qFromUnaligned<uint>(p));
p += 4;
}
# else
p += 4;
for ( ; p <= e; p += 4)
- h = _mm_crc32_u32(h, qUnalignedLoad<uint>(p - 4));
+ h = _mm_crc32_u32(h, qFromUnaligned<uint>(p - 4));
p -= 4;
len = e - p;
# endif
if (len & 2) {
- h = _mm_crc32_u16(h, qUnalignedLoad<ushort>(p));
+ h = _mm_crc32_u16(h, qFromUnaligned<ushort>(p));
p += 2;
}
if (sizeof(Char) == 1 && len & 1)
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 7dd02bf954..1762da2c8f 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -60,15 +60,6 @@ QT_BEGIN_NAMESPACE
const QListData::Data QListData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, { 0 } };
-static int grow(int size)
-{
- if (size_t(size) > (MaxAllocSize - QListData::DataHeaderSize) / sizeof(void *))
- qBadAlloc();
- // dear compiler: don't optimize me out.
- volatile int x = qAllocMore(size * sizeof(void *), QListData::DataHeaderSize) / sizeof(void *);
- return x;
-}
-
/*!
* Detaches the QListData by allocating new memory for a list which will be bigger
* than the copied one and is expected to grow further.
@@ -84,12 +75,12 @@ QListData::Data *QListData::detach_grow(int *idx, int num)
Data *x = d;
int l = x->end - x->begin;
int nl = l + num;
- int alloc = grow(nl);
- Data* t = static_cast<Data *>(::malloc(DataHeaderSize + alloc * sizeof(void *)));
+ auto blockInfo = qCalculateGrowingBlockSize(nl, sizeof(void *), DataHeaderSize);
+ Data* t = static_cast<Data *>(::malloc(blockInfo.size));
Q_CHECK_PTR(t);
+ t->alloc = int(uint(blockInfo.elementCount));
t->ref.initializeOwned();
- t->alloc = alloc;
// The space reservation algorithm's optimization is biased towards appending:
// Something which looks like an append will put the data at the beginning,
// while something which looks like a prepend will put it in the middle
@@ -99,12 +90,12 @@ QListData::Data *QListData::detach_grow(int *idx, int num)
int bg;
if (*idx < 0) {
*idx = 0;
- bg = (alloc - nl) >> 1;
+ bg = (t->alloc - nl) >> 1;
} else if (*idx > l) {
*idx = l;
bg = 0;
} else if (*idx < (l >> 1)) {
- bg = (alloc - nl) >> 1;
+ bg = (t->alloc - nl) >> 1;
} else {
bg = 0;
}
@@ -126,7 +117,7 @@ QListData::Data *QListData::detach_grow(int *idx, int num)
QListData::Data *QListData::detach(int alloc)
{
Data *x = d;
- Data* t = static_cast<Data *>(::malloc(DataHeaderSize + alloc * sizeof(void *)));
+ Data* t = static_cast<Data *>(::malloc(qCalculateBlockSize(alloc, sizeof(void*), DataHeaderSize)));
Q_CHECK_PTR(t);
t->ref.initializeOwned();
@@ -146,7 +137,7 @@ QListData::Data *QListData::detach(int alloc)
void QListData::realloc(int alloc)
{
Q_ASSERT(!d->ref.isShared());
- Data *x = static_cast<Data *>(::realloc(d, DataHeaderSize + alloc * sizeof(void *)));
+ Data *x = static_cast<Data *>(::realloc(d, qCalculateBlockSize(alloc, sizeof(void *), DataHeaderSize)));
Q_CHECK_PTR(x);
d = x;
@@ -158,12 +149,12 @@ void QListData::realloc(int alloc)
void QListData::realloc_grow(int growth)
{
Q_ASSERT(!d->ref.isShared());
- int alloc = grow(d->alloc + growth);
- Data *x = static_cast<Data *>(::realloc(d, DataHeaderSize + alloc * sizeof(void *)));
+ auto r = qCalculateGrowingBlockSize(d->alloc + growth, sizeof(void *), DataHeaderSize);
+ Data *x = static_cast<Data *>(::realloc(d, r.size));
Q_CHECK_PTR(x);
d = x;
- d->alloc = alloc;
+ d->alloc = int(uint(r.elementCount));
}
void QListData::dispose(Data *d)
diff --git a/src/corelib/tools/qmessageauthenticationcode.cpp b/src/corelib/tools/qmessageauthenticationcode.cpp
index 9b91474283..9a84191452 100644
--- a/src/corelib/tools/qmessageauthenticationcode.cpp
+++ b/src/corelib/tools/qmessageauthenticationcode.cpp
@@ -46,9 +46,29 @@
available on all platforms (MSVC 2008, for example), we #define them to the
Qt equivalents.
*/
+
+#ifdef uint64_t
+#undef uint64_t
+#endif
+
#define uint64_t QT_PREPEND_NAMESPACE(quint64)
+
+#ifdef uint32_t
+#undef uint32_t
+#endif
+
#define uint32_t QT_PREPEND_NAMESPACE(quint32)
+
+#ifdef uint8_t
+#undef uint8_t
+#endif
+
#define uint8_t QT_PREPEND_NAMESPACE(quint8)
+
+#ifdef int_least16_t
+#undef int_least16_t
+#endif
+
#define int_least16_t QT_PREPEND_NAMESPACE(qint16)
// Header from rfc6234 with 1 modification:
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 7b1d94c501..d4edf459de 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -724,26 +724,4 @@ void qDumpCPUFeatures()
puts("");
}
-/*!
- \internal
- \fn T qUnalignedLoad(const void *ptr)
- \since 5.6.1
-
- Loads a \c{T} from address \a ptr, which may be misaligned.
-
- Use of this function avoid the undefined behavior that the C++ standard
- otherwise attributes to unaligned loads.
-*/
-
-/*!
- \internal
- \fn void qUnalignedStore(void *ptr, T t)
- \since 5.6.1
-
- Stores \a t to address \a ptr, which may be misaligned.
-
- Use of this function avoid the undefined behavior that the C++ standard
- otherwise attributes to unaligned stores.
-*/
-
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 6c1ee25234..c79bced52e 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -581,7 +581,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l)
// we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes)
if (uc + offset + 7 < e) {
// same, but we're using an 8-byte load
- __m128i chunk = _mm_cvtsi64_si128(qUnalignedLoad<long long>(c + offset));
+ __m128i chunk = _mm_cvtsi64_si128(qFromUnaligned<long long>(c + offset));
__m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask);
__m128i ucdata = _mm_loadu_si128((const __m128i*)(uc + offset));
@@ -1757,10 +1757,13 @@ void QString::resize(int size, QChar fillChar)
void QString::reallocData(uint alloc, bool grow)
{
+ size_t blockSize;
if (grow) {
- if (alloc > (uint(MaxAllocSize) - sizeof(Data)) / sizeof(QChar))
- qBadAlloc();
- alloc = qAllocMore(alloc * sizeof(QChar), sizeof(Data)) / sizeof(QChar);
+ auto r = qCalculateGrowingBlockSize(alloc, sizeof(QChar), sizeof(Data));
+ blockSize = r.size;
+ alloc = uint(r.elementCount);
+ } else {
+ blockSize = qCalculateBlockSize(alloc, sizeof(QChar), sizeof(Data));
}
if (d->ref.isShared() || IS_RAW_DATA(d)) {
@@ -1774,7 +1777,7 @@ void QString::reallocData(uint alloc, bool grow)
Data::deallocate(d);
d = x;
} else {
- Data *p = static_cast<Data *>(::realloc(d, sizeof(Data) + alloc * sizeof(QChar)));
+ Data *p = static_cast<Data *>(::realloc(d, blockSize));
Q_CHECK_PTR(p);
d = p;
d->alloc = alloc;
@@ -2343,8 +2346,7 @@ QString &QString::remove(QChar ch, Qt::CaseSensitivity cs)
*/
QString &QString::replace(int pos, int len, const QString &after)
{
- QString copy = after;
- return replace(pos, len, copy.constData(), copy.length());
+ return replace(pos, len, after.constData(), after.length());
}
/*!
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 8040365581..c2630c8593 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -47,6 +47,8 @@
#include <qdebug.h>
+#include "qlocale_tools_p.h"
+
#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -376,39 +378,126 @@ static QDate calculatePosixDate(const QByteArray &dateRule, int year)
}
}
-static QTime parsePosixTime(const QByteArray &timeRule)
+// returns the time in seconds, INT_MIN if we failed to parse
+static int parsePosixTime(const char *begin, const char *end)
{
- // Format "HH:mm:ss", put check parts count just in case
- QList<QByteArray> parts = timeRule.split(':');
- int count = parts.count();
- if (count == 3)
- return QTime(parts.at(0).toInt(), parts.at(1).toInt(), parts.at(2).toInt());
- else if (count == 2)
- return QTime(parts.at(0).toInt(), parts.at(1).toInt(), 0);
- else if (count == 1)
- return QTime(parts.at(0).toInt(), 0, 0);
- return QTime(2, 0, 0);
+ // Format "hh[:mm[:ss]]"
+ int hour, min = 0, sec = 0;
+
+ // Note that the calls to qstrtoll do *not* check the end pointer, which
+ // means they proceed until they find a non-digit. We check that we're
+ // still in range at the end, but we may have read from past end. It's the
+ // caller's responsibility to ensure that begin is part of a
+ // null-terminated string.
+
+ bool ok = false;
+ hour = qstrtoll(begin, &begin, 10, &ok);
+ if (!ok || hour < 0)
+ return INT_MIN;
+ if (begin < end && *begin == ':') {
+ // minutes
+ ++begin;
+ min = qstrtoll(begin, &begin, 10, &ok);
+ if (!ok || min < 0)
+ return INT_MIN;
+
+ if (begin < end && *begin == ':') {
+ // seconds
+ ++begin;
+ sec = qstrtoll(begin, &begin, 10, &ok);
+ if (!ok || sec < 0)
+ return INT_MIN;
+ }
+ }
+
+ // we must have consumed everything
+ if (begin != end)
+ return INT_MIN;
+
+ return (hour * 60 + min) * 60 + sec;
}
-static int parsePosixOffset(const QByteArray &timeRule)
+static QTime parsePosixTransitionTime(const QByteArray &timeRule)
+{
+ // Format "hh[:mm[:ss]]"
+ int value = parsePosixTime(timeRule.constBegin(), timeRule.constEnd());
+ if (value == INT_MIN) {
+ // if we failed to parse, return 02:00
+ return QTime(2, 0, 0);
+ }
+ return QTime::fromMSecsSinceStartOfDay(value * 1000);
+}
+
+static int parsePosixOffset(const char *begin, const char *end)
{
// Format "[+|-]hh[:mm[:ss]]"
- QList<QByteArray> parts = timeRule.split(':');
- int count = parts.count();
- if (count == 3) {
- int hour = parts.at(0).toInt();
- int sign = hour >= 0 ? -1 : 1;
- return sign * ((qAbs(hour) * 60 * 60) + (parts.at(1).toInt() * 60) + parts.at(2).toInt());
- } else if (count == 2) {
- int hour = parts.at(0).toInt();
- int sign = hour >= 0 ? -1 : 1;
- return sign * ((qAbs(hour) * 60 * 60) + (parts.at(1).toInt() * 60));
- } else if (count == 1) {
- int hour = parts.at(0).toInt();
- int sign = hour >= 0 ? -1 : 1;
- return sign * (qAbs(hour) * 60 * 60);
- }
- return 0;
+ // note that the sign is inverted because POSIX counts in hours West of GMT
+ bool negate = true;
+ if (*begin == '+') {
+ ++begin;
+ } else if (*begin == '-') {
+ negate = false;
+ ++begin;
+ }
+
+ int value = parsePosixTime(begin, end);
+ if (value == INT_MIN)
+ return value;
+ return negate ? -value : value;
+}
+
+static inline bool asciiIsLetter(char ch)
+{
+ ch |= 0x20; // lowercases if it is a letter, otherwise just corrupts ch
+ return ch >= 'a' && ch <= 'z';
+}
+
+// Returns the zone name, the offset (in seconds) and advances \a begin to
+// where the parsing ended. Returns a zone of INT_MIN in case an offset
+// couldn't be read.
+static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const char *end)
+{
+ static const char offsetChars[] = "0123456789:";
+ QPair<QString, int> result = qMakePair(QString(), INT_MIN);
+
+ const char *nameBegin = pos;
+ const char *nameEnd;
+ Q_ASSERT(pos < end);
+
+ if (*pos == '<') {
+ nameBegin = pos + 1; // skip the '<'
+ nameEnd = nameBegin;
+ while (nameEnd < end && *nameEnd != '>') {
+ // POSIX says only alphanumeric, but we allow anything
+ ++nameEnd;
+ }
+ pos = nameEnd + 1; // skip the '>'
+ } else {
+ nameBegin = pos;
+ nameEnd = nameBegin;
+ while (nameEnd < end && asciiIsLetter(*nameEnd))
+ ++nameEnd;
+ pos = nameEnd;
+ }
+ if (nameEnd - nameBegin < 3)
+ return result; // name must be at least 3 characters long
+
+ // zone offset, form [+-]hh:mm:ss
+ const char *zoneBegin = pos;
+ const char *zoneEnd = pos;
+ if (zoneEnd < end && (zoneEnd[0] == '+' || zoneEnd[0] == '-'))
+ ++zoneEnd;
+ while (zoneEnd < end) {
+ if (strchr(offsetChars, char(*zoneEnd)) == NULL)
+ break;
+ ++zoneEnd;
+ }
+
+ result.first = QString::fromUtf8(nameBegin, nameEnd - nameBegin);
+ if (zoneEnd > zoneBegin)
+ result.second = parsePosixOffset(zoneBegin, zoneEnd);
+ pos = zoneEnd;
+ return result;
}
static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule,
@@ -425,58 +514,45 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
// POSIX Format is like "TZ=CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00"
// i.e. "std offset dst [offset],start[/time],end[/time]"
- // See http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
+ // See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
QList<QByteArray> parts = posixRule.split(',');
- QString name = QString::fromUtf8(parts.at(0));
- QString stdName;
- QString stdOffsetString;
- QString dstName;
- QString dstOffsetString;
- bool parsedStdName = false;
- bool parsedStdOffset = false;
- for (int i = 0; i < name.size(); ++i) {
- if (name.at(i).isLetter()) {
- if (parsedStdName) {
- parsedStdOffset = true;
- dstName.append(name.at(i));
- } else {
- stdName.append(name.at(i));
+ QPair<QString, int> stdZone, dstZone;
+ {
+ const QByteArray &zoneinfo = parts.at(0);
+ const char *begin = zoneinfo.constBegin();
+
+ stdZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd());
+ if (stdZone.second == INT_MIN) {
+ stdZone.second = 0; // reset to UTC if we failed to parse
+ } else if (begin < zoneinfo.constEnd()) {
+ dstZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd());
+ if (dstZone.second == INT_MIN) {
+ // if the dst offset isn't provided, it is 1 hour ahead of the standard offset
+ dstZone.second = stdZone.second + (60 * 60);
}
- } else {
- parsedStdName = true;
- if (parsedStdOffset)
- dstOffsetString.append(name.at(i));
- else
- stdOffsetString.append(name.at(i));
}
}
- int utcOffset = parsePosixOffset(stdOffsetString.toUtf8());
-
// If only the name part then no transitions
if (parts.count() == 1) {
QTimeZonePrivate::Data data;
data.atMSecsSinceEpoch = lastTranMSecs;
- data.offsetFromUtc = utcOffset;
- data.standardTimeOffset = utcOffset;
+ data.offsetFromUtc = stdZone.second;
+ data.standardTimeOffset = stdZone.second;
data.daylightTimeOffset = 0;
- data.abbreviation = stdName;
+ data.abbreviation = stdZone.first;
result << data;
return result;
}
- // If not populated the total dst offset is 1 hour
- int dstOffset = utcOffset + (60 * 60);
- if (!dstOffsetString.isEmpty())
- dstOffset = parsePosixOffset(dstOffsetString.toUtf8());
// Get the std to dst transtion details
QList<QByteArray> dstParts = parts.at(1).split('/');
QByteArray dstDateRule = dstParts.at(0);
QTime dstTime;
if (dstParts.count() > 1)
- dstTime = parsePosixTime(dstParts.at(1));
+ dstTime = parsePosixTransitionTime(dstParts.at(1));
else
dstTime = QTime(2, 0, 0);
@@ -485,25 +561,25 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
QByteArray stdDateRule = stdParts.at(0);
QTime stdTime;
if (stdParts.count() > 1)
- stdTime = parsePosixTime(stdParts.at(1));
+ stdTime = parsePosixTransitionTime(stdParts.at(1));
else
stdTime = QTime(2, 0, 0);
for (int year = startYear; year <= endYear; ++year) {
QTimeZonePrivate::Data dstData;
QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC);
- dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (utcOffset * 1000);
- dstData.offsetFromUtc = dstOffset;
- dstData.standardTimeOffset = utcOffset;
- dstData.daylightTimeOffset = dstOffset - utcOffset;
- dstData.abbreviation = dstName;
+ dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.second * 1000);
+ dstData.offsetFromUtc = dstZone.second;
+ dstData.standardTimeOffset = stdZone.second;
+ dstData.daylightTimeOffset = dstZone.second - stdZone.second;
+ dstData.abbreviation = dstZone.first;
QTimeZonePrivate::Data stdData;
QDateTime std(calculatePosixDate(stdDateRule, year), stdTime, Qt::UTC);
- stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstOffset * 1000);
- stdData.offsetFromUtc = utcOffset;
- stdData.standardTimeOffset = utcOffset;
+ stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.second * 1000);
+ stdData.offsetFromUtc = stdZone.second;
+ stdData.standardTimeOffset = stdZone.second;
stdData.daylightTimeOffset = 0;
- stdData.abbreviation = stdName;
+ stdData.abbreviation = stdZone.first;
// Part of the high year will overflow
if (year == 292278994 && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) {
if (dstData.atMSecsSinceEpoch > 0) {
diff --git a/src/corelib/tools/qtools_p.h b/src/corelib/tools/qtools_p.h
index 5ec153c818..09adee5586 100644
--- a/src/corelib/tools/qtools_p.h
+++ b/src/corelib/tools/qtools_p.h
@@ -52,7 +52,7 @@
//
#include "QtCore/qglobal.h"
-#include <limits>
+#include <limits.h>
QT_BEGIN_NAMESPACE
@@ -88,11 +88,19 @@ Q_DECL_CONSTEXPR inline int fromOct(uint c) Q_DECL_NOTHROW
// We typically need an extra bit for qNextPowerOfTwo when determining the next allocation size.
enum {
- MaxAllocSize = (1 << (std::numeric_limits<int>::digits - 1)) - 1
+ MaxAllocSize = INT_MAX
+};
+
+struct CalculateGrowingBlockSizeResult {
+ size_t size;
+ size_t elementCount;
};
// implemented in qbytearray.cpp
-int Q_CORE_EXPORT qAllocMore(int alloc, int extra) Q_DECL_NOTHROW;
+size_t Q_CORE_EXPORT Q_DECL_CONST_FUNCTION
+qCalculateBlockSize(size_t elementCount, size_t elementSize, size_t headerSize = 0) Q_DECL_NOTHROW;
+CalculateGrowingBlockSizeResult Q_CORE_EXPORT Q_DECL_CONST_FUNCTION
+qCalculateGrowingBlockSize(size_t elementCount, size_t elementSize, size_t headerSize = 0) Q_DECL_NOTHROW ;
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index fea50f4c34..b68ca87063 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -736,7 +736,7 @@ typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
const int itemsUntouched = abegin - d->begin();
// FIXME we could do a proper realloc, which copy constructs only needed data.
- // FIXME we ara about to delete data maybe it is good time to shrink?
+ // FIXME we are about to delete data - maybe it is good time to shrink?
// FIXME the shrink is also an issue in removeLast, that is just a copy + reduce of this.
if (d->alloc) {
detach();
@@ -756,7 +756,11 @@ typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
}
} else {
destruct(abegin, aend);
- memmove(abegin, aend, (d->size - itemsToErase - itemsUntouched) * sizeof(T));
+ // QTBUG-53605: static_cast<void *> masks clang errors of the form
+ // error: destination for this 'memmove' call is a pointer to class containing a dynamic class
+ // FIXME maybe use std::is_polymorphic (as soon as allowed) to avoid the memmove
+ memmove(static_cast<void *>(abegin), static_cast<void *>(aend),
+ (d->size - itemsToErase - itemsUntouched) * sizeof(T));
}
d->size -= itemsToErase;
}
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 8e62804025..3949d2c3ac 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -3025,10 +3025,14 @@ void QXmlStreamWriterPrivate::checkIfASCIICompatibleCodec()
{
#ifndef QT_NO_TEXTCODEC
Q_ASSERT(encoder);
- // assumes ASCII-compatibility for all 8-bit encodings
- QChar space = QLatin1Char(' ');
- const QByteArray bytes = encoder->fromUnicode(&space, 1);
- isCodecASCIICompatible = (bytes.count() == 1);
+ // test ASCII-compatibility using the letter 'a'
+ QChar letterA = QLatin1Char('a');
+ const QByteArray bytesA = encoder->fromUnicode(&letterA, 1);
+ const bool isCodecASCIICompatibleA = (bytesA.count() == 1) && (bytesA[0] == 0x61) ;
+ QChar letterLess = QLatin1Char('<');
+ const QByteArray bytesLess = encoder->fromUnicode(&letterLess, 1);
+ const bool isCodecASCIICompatibleLess = (bytesLess.count() == 1) && (bytesLess[0] == 0x3C) ;
+ isCodecASCIICompatible = isCodecASCIICompatibleA && isCodecASCIICompatibleLess ;
#else
isCodecASCIICompatible = true;
#endif
@@ -3790,7 +3794,8 @@ void QXmlStreamWriter::writeStartDocument(const QString &version)
#ifdef QT_NO_TEXTCODEC
d->write("iso-8859-1");
#else
- d->write(d->codec->name().constData(), d->codec->name().length());
+ const QByteArray name = d->codec->name();
+ d->write(name.constData(), name.length());
#endif
}
d->write("\"?>");
@@ -3813,7 +3818,8 @@ void QXmlStreamWriter::writeStartDocument(const QString &version, bool standalon
#ifdef QT_NO_TEXTCODEC
d->write("iso-8859-1");
#else
- d->write(d->codec->name().constData(), d->codec->name().length());
+ const QByteArray name = d->codec->name();
+ d->write(name.constData(), name.length());
#endif
}
if (standalone)