summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-05-24 16:27:08 +0200
committerLiang Qi <liang.qi@qt.io>2018-05-24 16:29:14 +0200
commitf82e5085169876e0ec7c1b744d021b068c281cfe (patch)
treea870e1f68ce62818a0793c4c78a67971e841e676 /src/corelib
parentf74d4fb1dacc682e2e6f4a44e4240f642a2c3b70 (diff)
parentee47999333dde1d38b73d04e142e05f06f8c56ed (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts: mkspecs/features/qt_common.prf src/corelib/tools/qstring.cpp src/plugins/platforms/windows/qwindowsmousehandler.cpp src/widgets/widgets/qmainwindowlayout_p.h Change-Id: I5df613008f6336f69b257d08e49a133d033a9d65
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/configure.json3
-rw-r--r--src/corelib/global/qnamespace.qdoc9
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp1
-rw-r--r--src/corelib/serialization/qjson.cpp43
-rw-r--r--src/corelib/tools/qlocale_unix.cpp34
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h11
-rw-r--r--src/corelib/tools/qstring.cpp89
8 files changed, 140 insertions, 52 deletions
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index b03cf2f9d5..18fc22f18f 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -562,7 +562,8 @@
},
"linkat": {
"label": "linkat()",
- "autoDetect": "config.linux",
+ "comment": "Currently only used by QTemporaryFile; linkat() exists on Android, but hardlink creation fails due to security rules",
+ "autoDetect": "config.linux && !config.android",
"condition": "tests.linkat",
"output": [ "privateFeature" ]
},
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 66a7a1e6b5..2fcc744092 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1334,7 +1334,14 @@
\omitvalue WA_WState_WindowOpacitySet
\omitvalue WA_WState_AcceptedTouchBeginEvent
\omitvalue WA_MacNoShadow
- \omitvalue WA_ContentsMarginsRespectsSafeArea
+ \value WA_ContentsMarginsRespectsSafeArea A QWidget respects the safe
+ area margins of a window by incorporating the margins into its contents'
+ margins by default. This means, that a QLayout will use the content area
+ of a widget for its layout, unless the Qt::WA_LayoutOnEntireRect attribute
+ is set. This along with a contents margin of 0 can be used on the actual
+ layout, to allow for example a background image to underlay the status bar and other
+ system areas on an iOS device, while still allowing child widgets of
+ that background to be inset based on the safe area.
*/
/*! \typedef Qt::HANDLE
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 5cc3a5937e..0ffc4ca634 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -114,6 +114,8 @@ static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newp
# if !QT_CONFIG(statx) && defined(SYS_statx)
static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struct statx *statxbuf)
{ return syscall(SYS_statx, dirfd, pathname, flag, mask, statxbuf); }
+# elif !QT_CONFIG(statx) && !defined(SYS_statx)
+# undef STATX_BASIC_STATS
# endif
# endif // !Q_OS_ANDROID
#endif
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 25d17ecd6b..6181bd579e 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4429,6 +4429,7 @@ QDebug operator<<(QDebug dbg, const QObject *o)
/*!
\macro Q_NAMESPACE
+ \relates QObject
\since 5.8
The Q_NAMESPACE macro can be used to add QMetaObject capabilities
diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp
index 592f6168dc..7912b5040c 100644
--- a/src/corelib/serialization/qjson.cpp
+++ b/src/corelib/serialization/qjson.cpp
@@ -326,38 +326,35 @@ int Value::usedStorage(const Base *b) const
return alignedSize(s);
}
+inline bool isValidValueOffset(uint offset, uint tableOffset)
+{
+ return offset >= sizeof(Base)
+ && offset + sizeof(uint) <= tableOffset;
+}
+
bool Value::isValid(const Base *b) const
{
- int offset = -1;
switch (type) {
+ case QJsonValue::Null:
+ case QJsonValue::Bool:
+ return true;
case QJsonValue::Double:
- if (latinOrIntValue)
- break;
- Q_FALLTHROUGH();
+ return latinOrIntValue || isValidValueOffset(value, b->tableOffset);
case QJsonValue::String:
+ if (!isValidValueOffset(value, b->tableOffset))
+ return false;
+ if (latinOrIntValue)
+ return asLatin1String(b).isValid(b->tableOffset - value);
+ return asString(b).isValid(b->tableOffset - value);
case QJsonValue::Array:
+ return isValidValueOffset(value, b->tableOffset)
+ && static_cast<Array *>(base(b))->isValid(b->tableOffset - value);
case QJsonValue::Object:
- offset = value;
- break;
- case QJsonValue::Null:
- case QJsonValue::Bool:
+ return isValidValueOffset(value, b->tableOffset)
+ && static_cast<Object *>(base(b))->isValid(b->tableOffset - value);
default:
- break;
- }
-
- if (offset == -1)
- return true;
- if (offset + sizeof(uint) > b->tableOffset || offset < (int)sizeof(Base))
- return false;
-
- int s = usedStorage(b);
- if (s < 0 || s > (int)b->tableOffset - offset)
return false;
- if (type == QJsonValue::Array)
- return static_cast<Array *>(base(b))->isValid(s);
- if (type == QJsonValue::Object)
- return static_cast<Object *>(base(b))->isValid(s);
- return true;
+ }
}
/*!
diff --git a/src/corelib/tools/qlocale_unix.cpp b/src/corelib/tools/qlocale_unix.cpp
index 095001e0a3..1a9184bca9 100644
--- a/src/corelib/tools/qlocale_unix.cpp
+++ b/src/corelib/tools/qlocale_unix.cpp
@@ -107,8 +107,36 @@ Q_GLOBAL_STATIC(QSystemLocaleData, qSystemLocaleData)
#ifndef QT_NO_SYSTEMLOCALE
+static bool contradicts(const QByteArray &maybe, const QByteArray &known)
+{
+ if (maybe.isEmpty())
+ return false;
+
+ /*
+ If \a known (our current best shot at deciding which language to use)
+ provides more information (e.g. script, country) than \a maybe (a
+ candidate to replace \a known) and \a maybe agrees with \a known in what
+ it does provide, we keep \a known; this happens when \a maybe comes from
+ LANGUAGE (usually a simple language code) and LANG includes script and/or
+ country. A textual comparison won't do because, for example, bn (Bengali)
+ isn't a prefix of ben_IN, but the latter is a refinement of the former.
+ (Meanwhile, bn is a prefix of bnt, Bantu; and a prefix of ben is be,
+ Belarusian. There are many more such prefixings between two- and
+ three-letter codes.)
+ */
+ QLocale::Language langm, langk;
+ QLocale::Script scriptm, scriptk;
+ QLocale::Country landm, landk;
+ QLocalePrivate::getLangAndCountry(maybe, langm, scriptm, landm);
+ QLocalePrivate::getLangAndCountry(known, langk, scriptk, landk);
+ return (langm != QLocale::AnyLanguage && langm != langk)
+ || (scriptm != QLocale::AnyScript && scriptm != scriptk)
+ || (landm != QLocale::AnyCountry && landm != landk);
+}
+
QLocale QSystemLocale::fallbackUiLocale() const
{
+ // See man 7 locale for precedence - LC_ALL beats LC_MESSAGES beats LANG:
QByteArray lang = qgetenv("LC_ALL");
if (lang.isEmpty())
lang = qgetenv("LC_MESSAGES");
@@ -118,12 +146,12 @@ QLocale QSystemLocale::fallbackUiLocale() const
if (lang.isEmpty() || lang == QByteArray("C") || lang == QByteArray("POSIX"))
return QLocale(QString::fromLatin1(lang));
- // if the locale is not the "C" locale and LANGUAGE is not empty, return
- // the first part of LANGUAGE if LANGUAGE is set and has a first part:
+ // ... otherwise, if the first part of LANGUAGE says more than or
+ // contradicts what we have, use that:
QByteArray language = qgetenv("LANGUAGE");
if (!language.isEmpty()) {
language = language.split(':').constFirst();
- if (!language.isEmpty())
+ if (contradicts(language, lang))
return QLocale(QString::fromLatin1(language));
}
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index a0e408b94a..bccf8c5740 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -246,7 +246,8 @@ namespace QtSharedPointer {
struct ExternalRefCountWithContiguousData: public ExternalRefCountData
{
typedef ExternalRefCountData Parent;
- T data;
+ typedef typename std::remove_cv<T>::type NoCVType;
+ NoCVType data;
static void deleter(ExternalRefCountData *self)
{
@@ -262,7 +263,7 @@ namespace QtSharedPointer {
}
static void noDeleter(ExternalRefCountData *) { }
- static inline ExternalRefCountData *create(T **ptr, DestroyerFn destroy)
+ static inline ExternalRefCountData *create(NoCVType **ptr, DestroyerFn destroy)
{
ExternalRefCountWithContiguousData *d =
static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
@@ -437,10 +438,12 @@ public:
# endif
typename Private::DestroyerFn noDestroy = &Private::noDeleter;
QSharedPointer result(Qt::Uninitialized);
- result.d = Private::create(&result.value, noDestroy);
+ typename std::remove_cv<T>::type *ptr;
+ result.d = Private::create(&ptr, noDestroy);
// now initialize the data
- new (result.data()) T(std::forward<Args>(arguments)...);
+ new (ptr) T(std::forward<Args>(arguments)...);
+ result.value = ptr;
result.d->destroyer = destroy;
result.d->setQObjectShared(result.value, true);
# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index f5accd0fec..a04b2f0d02 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -357,11 +357,20 @@ static bool simdTestMask(const char *&ptr, const char *end, quint32 maskval)
// character. Usually harmless.
bool qt_is_ascii(const char *&ptr, const char *end) Q_DECL_NOTHROW
{
-#if defined(__AVX2__)
- if (!simdTestMask(ptr, end, 0x80808080))
- return false;
-#elif defined(__SSE2__)
+#if defined(__SSE2__)
// Testing for the high bit can be done efficiently with just PMOVMSKB
+# if defined(__AVX2__)
+ while (ptr + 32 <= end) {
+ __m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr));
+ quint32 mask = _mm256_movemask_epi8(data);
+ if (mask) {
+ uint idx = qCountTrailingZeroBits(mask);
+ ptr += idx;
+ return false;
+ }
+ ptr += 32;
+ }
+# endif
while (ptr + 16 <= end) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
quint32 mask = _mm_movemask_epi8(data);
@@ -778,30 +787,70 @@ static int ucstrncmp(const QChar *a, const QChar *b, size_t l)
}
#endif // __mips_dsp
#ifdef __SSE2__
- const char *ptr = reinterpret_cast<const char*>(a);
- qptrdiff distance = reinterpret_cast<const char*>(b) - ptr;
- a += l & ~7;
- b += l & ~7;
- l &= 7;
-
- // we're going to read ptr[0..15] (16 bytes)
- for ( ; ptr + 15 < reinterpret_cast<const char *>(a); ptr += 16) {
- __m128i a_data = _mm_loadu_si128((const __m128i*)ptr);
- __m128i b_data = _mm_loadu_si128((const __m128i*)(ptr + distance));
+ const QChar *end = a + l;
+ qptrdiff offset = 0;
+
+ // we're going to read a[0..15] and b[0..15] (32 bytes)
+ for ( ; a + offset + 16 <= end; offset += 16) {
+#ifdef __AVX2__
+ __m256i a_data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(a + offset));
+ __m256i b_data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(b + offset));
+ __m256i result = _mm256_cmpeq_epi16(a_data, b_data);
+ uint mask = _mm256_movemask_epi8(result);
+#else
+ __m128i a_data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(a + offset));
+ __m128i a_data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(a + offset + 8));
+ __m128i b_data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(b + offset));
+ __m128i b_data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(b + offset + 8));
+ __m128i result1 = _mm_cmpeq_epi16(a_data1, b_data1);
+ __m128i result2 = _mm_cmpeq_epi16(a_data2, b_data2);
+ uint mask = _mm_movemask_epi8(result1) | (_mm_movemask_epi8(result2) << 16);
+#endif
+ mask = ~mask;
+ if (mask) {
+ // found a different character
+ uint idx = qCountTrailingZeroBits(mask);
+ return a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode();
+ }
+ }
+
+ // we're going to read a[0..7] and b[0..7] (16 bytes)
+ if (a + offset + 8 <= end) {
+ __m128i a_data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(a + offset));
+ __m128i b_data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(b + offset));
__m128i result = _mm_cmpeq_epi16(a_data, b_data);
uint mask = ~_mm_movemask_epi8(result);
if (ushort(mask)) {
- // found a different byte
+ // found a different character
uint idx = qCountTrailingZeroBits(mask);
- return reinterpret_cast<const QChar *>(ptr + idx)->unicode()
- - reinterpret_cast<const QChar *>(ptr + distance + idx)->unicode();
+ return a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode();
}
+
+ offset += 8;
}
+
+ // we're going to read a[0..3] and b[0..3] (8 bytes)
+ if (a + offset + 4 <= end) {
+ __m128i a_data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(a + offset));
+ __m128i b_data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(b + offset));
+ __m128i result = _mm_cmpeq_epi16(a_data, b_data);
+ uint mask = ~_mm_movemask_epi8(result);
+ if (uchar(mask)) {
+ // found a different character
+ uint idx = qCountTrailingZeroBits(mask);
+ return a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode();
+ }
+
+ offset += 4;
+ }
+
+ // reset l
+ l &= 3;
+
const auto lambda = [=](size_t i) -> int {
- return reinterpret_cast<const QChar *>(ptr)[i].unicode()
- - reinterpret_cast<const QChar *>(ptr + distance)[i].unicode();
+ return a[offset + i].unicode() - b[offset + i].unicode();
};
- return UnrollTailLoop<7>::exec(l, 0, lambda, lambda);
+ return UnrollTailLoop<3>::exec(l, 0, lambda, lambda);
#endif
#if defined(__ARM_NEON__) && defined(Q_PROCESSOR_ARM_64) // vaddv is only available on Aarch64
if (l >= 8) {