From 5b37c9f7d3153a756af8fa89b2467c87a3021a8b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Apr 2016 13:35:30 -0700 Subject: Work around Clang false-positive warning on returning default parameters Clang 3.8 and Apple Clang 7.x seem to think that the parameter is a temporary. See https://llvm.org/bugs/show_bug.cgi?id=26396 Task-number: QTBUG-52134 Change-Id: Id75834dab9ed466e94c7ffff1444b6f2424d7fb7 Reviewed-by: Jake Petroules --- src/corelib/tools/qmap.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index fe9ddaaa32..ed49e70f4e 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -634,6 +634,8 @@ Q_INLINE_TEMPLATE void QMap::clear() *this = QMap(); } +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wreturn-stack-address") template Q_INLINE_TEMPLATE const T QMap::value(const Key &akey, const T &adefaultValue) const @@ -642,6 +644,8 @@ Q_INLINE_TEMPLATE const T QMap::value(const Key &akey, const T &adefault return n ? n->value : adefaultValue; } +QT_WARNING_POP + template Q_INLINE_TEMPLATE const T QMap::operator[](const Key &akey) const { -- cgit v1.2.3 From 9def501433e80e1a45c0d7888b9ceba4e32ca1fa Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 18 Apr 2016 23:27:12 +0200 Subject: QString: Avoid searching for a needle which is longer than the hay Avoid incurring the cost of converting the latin1 data in that case. Several existing QString unit tests excercise the new code path. Task-number: QTBUG-52617 Change-Id: I27256d9e7db34f09543e244a79d754ff7932f0d0 Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 10d3441d2c..983d1213d9 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -10005,6 +10005,9 @@ static inline int qt_find_latin1_string(const QChar *haystack, int size, QLatin1String needle, int from, Qt::CaseSensitivity cs) { + if (size < needle.size()) + return -1; + const char *latin1 = needle.latin1(); int len = needle.size(); QVarLengthArray s(len); -- cgit v1.2.3 From 0909a94af2d274840697e4ae25cc14b3f5eb6197 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 24 Apr 2016 00:07:28 +0200 Subject: QtCore: mark more types as primitive/movable These types are held in QVarLengthArrays, so benefit from being trivially relocatable. They are also part of the private API, so there's no BC issues with potential uses of these types in QList. Change-Id: I8adc0c801885f8fffa05eb1f173d7e4bb085ba7b Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qharfbuzz_p.h | 1 + src/corelib/tools/qunicodetools_p.h | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qharfbuzz_p.h b/src/corelib/tools/qharfbuzz_p.h index 3b69a2e4f6..cc4d9bbd85 100644 --- a/src/corelib/tools/qharfbuzz_p.h +++ b/src/corelib/tools/qharfbuzz_p.h @@ -348,6 +348,7 @@ Q_CORE_EXPORT HB_Face qHBLoadFace(HB_Face face); Q_DECLARE_TYPEINFO(HB_GlyphAttributes, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(HB_FixedPoint, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(HB_ScriptItem, Q_PRIMITIVE_TYPE); QT_END_NAMESPACE diff --git a/src/corelib/tools/qunicodetools_p.h b/src/corelib/tools/qunicodetools_p.h index 1103f28452..5cde188656 100644 --- a/src/corelib/tools/qunicodetools_p.h +++ b/src/corelib/tools/qunicodetools_p.h @@ -77,6 +77,10 @@ struct ScriptItem int script; }; +} // namespace QUnicodeTools +Q_DECLARE_TYPEINFO(QUnicodeTools::ScriptItem, Q_PRIMITIVE_TYPE); +namespace QUnicodeTools { + enum CharAttributeOption { GraphemeBreaks = 0x01, WordBreaks = 0x02, -- cgit v1.2.3 From 31c7b24aa5f57fbe8258c9e9845c8d630af4aec1 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 1 Apr 2016 23:55:25 +0200 Subject: Silence MSVC warnings when using certain std algorithms The MSVC STL warns when passing naked pointers as non-bounded iterators to algorithms such as std::equal and std::copy, in an attempt to inform users that the range specified by that iterator has an implicit minimum size that the caller of the algorithm must ensure is met: warning C4996: 'std::_Equal1': Function call with parameters that may be unsafe - \ this call relies on the caller to check that the passed values are correct. To \ disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to \ use Visual C++ 'Checked Iterators' When building Qt, as well as when building user projects with qmake (cf. 0a76b6bc7f98900ea884cd10ccca1a332e5bdba5), we globally disable this warning (with -D_SCL_SECURE_NO_WARNINGS), but since we started using STL algorithms in public headers (e.g. in qvector.h), users get this warning in their own projects now, unless they, too, define said macro. But such a requirement is against the Qt policy to have headers that are warning-free as much as possible. The suggested way of fixing this warning is to wrap the naked pointer in a stdext::unchecked_array_iterator before passing it to the algorithm, cf. examples in https://msdn.microsoft.com/en-us/library/ttcz0bys%28v=vs.120%29.aspx or, together with the capacity-made-explicit, in a stdext::checked_array_iterator. To avoid ifdefs for platforms that don't have these extensions (which, incidentally, for the unchecked case, includes MSVC 2012), wrap the calls in macros. The end game here is to drop -D_SCL_SECURE_NO_WARNINGS, at least for public headers, even though this commit also adds the wrapper to implementation and private header files. An alternative to the wrapper would have been the version of std::equal that takes four iterators. However, that is a C++14 library feature, while this version of Qt still needs to compile with a C++98 compiler, and, more importantly, there isn't, and never will be, a corresponding 4-iterator version of std::copy. Task-number: QTBUG-47948 Done-with: Stephen Kelly Change-Id: I1bbab257fb5f1c5042939c382a412b596112ff26 Reviewed-by: Stephen Kelly --- src/corelib/tools/qlist.h | 2 +- src/corelib/tools/qvarlengtharray.h | 7 ++++--- src/corelib/tools/qvector.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 9a57a2c6a5..e04a6be1ab 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -846,7 +846,7 @@ inline bool QList::op_eq_impl(const QList &l, QListData::ArrayCompatibleLayou const T *lb = reinterpret_cast(l.p.begin()); const T *b = reinterpret_cast(p.begin()); const T *e = reinterpret_cast(p.end()); - return std::equal(b, e, lb); + return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(lb, l.p.size())); } template diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index bb15d66439..8371352061 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -96,7 +96,8 @@ public: QVarLengthArray &operator=(std::initializer_list list) { resize(list.size()); - std::copy(list.begin(), list.end(), this->begin()); + std::copy(list.begin(), list.end(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size())); return *this; } #endif @@ -467,7 +468,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray::iterator QVarLengthA int l = int(aend - ptr); int n = l - f; if (QTypeInfo::isComplex) { - std::copy(ptr + l, ptr + s, ptr + f); + std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f)); T *i = ptr + s; T *b = ptr + s - n; while (i != b) { @@ -489,7 +490,7 @@ bool operator==(const QVarLengthArray &l, const QVarLengthArray diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 3ce33fb477..691872cb36 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -767,7 +767,7 @@ bool QVector::operator==(const QVector &v) const const T *vb = v.d->begin(); const T *b = d->begin(); const T *e = d->end(); - return std::equal(b, e, vb); + return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(vb, v.d->size)); } template -- cgit v1.2.3 From a1e3a0daed6c056c3b957151605f0f277fd38d3c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 25 Mar 2016 10:40:44 +0100 Subject: QString: Fix UBs (signed overflow) in hashed string search Similar change to 390ea21873cf229447c2dcaea85a40e472fab03c, but more extensive because the hash variables were not, yet, of unsigned type. This brings the three hashed string search algorithms in QtBase (in QString, QByteArray and QByteArrayMatcher) in line again. Found by UBSan, fixing the following bunch of errors: tools/qstring.cpp:3080:38: runtime error: left shift of negative value -1291179264 tools/qstring.cpp:3081:42: runtime error: left shift of negative value -1291179264 tools/qstring.cpp:3091:13: runtime error: left shift of 73 by 26 places cannot be represented in type 'int' tools/qstring.cpp:3091:13: runtime error: left shift of negative value -1255957171 tools/qstring.cpp:3091:13: runtime error: signed integer overflow: 1783052986 - -1207959552 cannot be represented in type 'int' tools/qstring.cpp:3097:37: runtime error: left shift of negative value -1298753576 tools/qstring.cpp:3098:41: runtime error: left shift of negative value -1298753576 tools/qstring.cpp:3107:13: runtime error: left shift of negative value -1508912760 tools/qstring.cpp:3158:38: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3159:42: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3169:13: runtime error: left shift of negative value -1657715810 tools/qstring.cpp:3173:38: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3174:42: runtime error: left shift of negative value -677037574 tools/qstring.cpp:3183:13: runtime error: left shift of negative value -1657715810 Change-Id: I1436eb61369919df9fe34251f863dd54fb58af98 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qstring.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 983d1213d9..6bbaf05fef 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -705,8 +705,8 @@ static int findChar(const QChar *str, int len, QChar ch, int from, } #define REHASH(a) \ - if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \ - hashHaystack -= (a) << sl_minus_1; \ + if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \ + hashHaystack -= uint(a) << sl_minus_1; \ hashHaystack <<= 1 inline bool qIsUpper(char ch) @@ -3072,8 +3072,9 @@ int qFindString( const ushort *needle = (const ushort *)needle0; const ushort *haystack = (const ushort *)haystack0 + from; const ushort *end = (const ushort *)haystack0 + (l-sl); - const int sl_minus_1 = sl-1; - int hashNeedle = 0, hashHaystack = 0, idx; + const uint sl_minus_1 = sl - 1; + uint hashNeedle = 0, hashHaystack = 0; + int idx; if (cs == Qt::CaseSensitive) { for (idx = 0; idx < sl; ++idx) { @@ -3148,10 +3149,11 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee const ushort *end = haystack; haystack += from; - const int sl_minus_1 = sl-1; + const uint sl_minus_1 = sl - 1; const ushort *n = needle+sl_minus_1; const ushort *h = haystack+sl_minus_1; - int hashNeedle = 0, hashHaystack = 0, idx; + uint hashNeedle = 0, hashHaystack = 0; + int idx; if (cs == Qt::CaseSensitive) { for (idx = 0; idx < sl; ++idx) { -- cgit v1.2.3 From 3df159ba174c1775a0e77d2305a639eeab1ea71d Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 30 Jan 2016 10:18:25 +0400 Subject: Improve the script itemization algorithm to match Unicode 8.0 Override preceding Common-s with a subsequent non-Inherited, non-Common script. This produces longer script runs, which automagically improves the shaping quality (as we don't lose the context anymore), the shaping performance (as we're typically shape a fewer runs), and the fallback font selection (when the font supports more than just a single language/script). Task-number: QTBUG-29930 Change-Id: I1c55af30bd397871d7f1f6e062605517f5a7e5a1 Reviewed-by: Lars Knoll Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/tools/qunicodetools.cpp | 71 +++++++++++++------------------------ 1 file changed, 24 insertions(+), 47 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qunicodetools.cpp b/src/corelib/tools/qunicodetools.cpp index 52e7b5a53f..fad4267edc 100644 --- a/src/corelib/tools/qunicodetools.cpp +++ b/src/corelib/tools/qunicodetools.cpp @@ -685,10 +685,10 @@ Q_CORE_EXPORT void initCharAttributes(const ushort *string, int length, Q_CORE_EXPORT void initScripts(const ushort *string, int length, uchar *scripts) { int sor = 0; - int eor = -1; + int eor = 0; uchar script = QChar::Script_Common; - for (int i = 0; i < length; ++i) { - eor = i; + + for (int i = 0; i < length; ++i, eor = i) { uint ucs4 = string[i]; if (QChar::isHighSurrogate(ucs4) && i + 1 < length) { ushort low = string[i + 1]; @@ -700,60 +700,37 @@ Q_CORE_EXPORT void initScripts(const ushort *string, int length, uchar *scripts) const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ucs4); - if (Q_LIKELY(prop->script == script || prop->script <= QChar::Script_Inherited)) + uchar nscript = prop->script; + + if (Q_LIKELY(nscript == script || nscript <= QChar::Script_Common)) continue; + // inherit preceding Common-s + if (Q_UNLIKELY(script <= QChar::Script_Common)) { + // also covers a case where the base character of Common script followed + // by one or more combining marks of non-Inherited, non-Common script + script = nscript; + continue; + } + // Never break between a combining mark (gc= Mc, Mn or Me) and its base character. // Thus, a combining mark — whatever its script property value is — should inherit // the script property value of its base character. static const int test = (FLAG(QChar::Mark_NonSpacing) | FLAG(QChar::Mark_SpacingCombining) | FLAG(QChar::Mark_Enclosing)); - if (Q_UNLIKELY(FLAG(prop->category) & test)) { - // In cases where the base character itself has the Common script property value, - // and it is followed by one or more combining marks with a specific script property value, - // it may be even better for processing to let the base acquire the script property value - // from the first mark. This approach can be generalized by treating all the characters - // of a combining character sequence as having the script property value - // of the first non-Inherited, non-Common character in the sequence if there is one, - // and otherwise treating all the characters as having the Common script property value. - if (Q_LIKELY(script > QChar::Script_Common || prop->script <= QChar::Script_Common)) - continue; - - script = QChar::Script(prop->script); - } - -#if 0 // ### Disabled due to regressions. The font selection algorithm is not prepared for this change. - if (Q_LIKELY(script != QChar::Script_Common)) { - // override preceding Common-s - while (sor > 0 && scripts[sor - 1] == QChar::Script_Common) - --sor; - } else { - // see if we are inheriting preceding run - if (sor > 0) - script = scripts[sor - 1]; - } -#endif + if (Q_UNLIKELY(FLAG(prop->category) & test)) + continue; - while (sor < eor) - scripts[sor++] = script; + Q_ASSERT(script > QChar::Script_Common); + Q_ASSERT(sor < eor); + ::memset(scripts + sor, script, (eor - sor) * sizeof(uchar)); + sor = eor; - script = prop->script; - } - eor = length; - -#if 0 // ### Disabled due to regressions. The font selection algorithm is not prepared for this change. - if (Q_LIKELY(script != QChar::Script_Common)) { - // override preceding Common-s - while (sor > 0 && scripts[sor - 1] == QChar::Script_Common) - --sor; - } else { - // see if we are inheriting preceding run - if (sor > 0) - script = scripts[sor - 1]; + script = nscript; } -#endif - while (sor < eor) - scripts[sor++] = script; + Q_ASSERT(script >= QChar::Script_Common); + Q_ASSERT(eor == length); + ::memset(scripts + sor, script, (eor - sor) * sizeof(uchar)); } } // namespace QUnicodeTools -- cgit v1.2.3 From ef7b0df4192b390c70a5e848bbe7c397daaefcce Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 26 Apr 2016 14:56:32 -0700 Subject: Fix QArrayData::allocate() to guard against integer overflows The proper solution with qCalculateBlockSize will come for Qt 5.7. Change-Id: Ifea6e497f11a461db432ffff14490788fc522eb7 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qarraydata.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index d9519745b0..fa6556f7d9 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include +#include #include #include @@ -87,16 +88,22 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, if (capacity > std::numeric_limits::max() / objectSize) return 0; - size_t alloc = objectSize * capacity; + size_t alloc; + if (mul_overflow(objectSize, capacity, &alloc)) + return 0; - // Make sure qAllocMore won't overflow. + // 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); } - size_t allocSize = headerSize + objectSize * capacity; + size_t allocSize; + if (mul_overflow(objectSize, capacity, &allocSize)) + return 0; + if (add_overflow(allocSize, headerSize, &allocSize)) + return 0; QArrayData *header = static_cast(::malloc(allocSize)); if (header) { -- cgit v1.2.3 From 9366a8be1eb7cfa5a5cb3650ae6230b46bb7e538 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 25 Apr 2016 14:43:43 +0200 Subject: Add an early-out to QVector::operator+= and QHash::unite for empty LHS If the container being added to is default constructed and has never been modified, we don't have to do all the checking and iterating. Instead we can just assign with operator=. If the LHS is merely empty, we could lose reserve()d capacity, so only do this for a shared-null LHS. Change-Id: If1e3342662d10833babc7ab847ada0285073723b Reviewed-by: Marc Mutz Reviewed-by: Milian Wolff --- src/corelib/tools/qhash.h | 14 +++++++++----- src/corelib/tools/qvector.h | 36 ++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 21 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 5e3016d313..b15dc7b07b 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -554,11 +554,15 @@ QHash::createNode(uint ah, const Key &akey, const T &avalue, Node **anex template Q_INLINE_TEMPLATE QHash &QHash::unite(const QHash &other) { - QHash copy(other); - const_iterator it = copy.constEnd(); - while (it != copy.constBegin()) { - --it; - insertMulti(it.key(), it.value()); + if (d == &QHashData::shared_null) { + *this = other; + } else { + QHash copy(other); + const_iterator it = copy.constEnd(); + while (it != copy.constBegin()) { + --it; + insertMulti(it.key(), it.value()); + } } return *this; } diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 13ae121450..806a127cc2 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -793,24 +793,28 @@ QVector &QVector::fill(const T &from, int asize) template QVector &QVector::operator+=(const QVector &l) { - uint newSize = d->size + l.d->size; - const bool isTooSmall = newSize > d->alloc; - if (!isDetached() || isTooSmall) { - QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); - reallocData(d->size, isTooSmall ? newSize : d->alloc, opt); - } + if (d == Data::sharedNull()) { + *this = l; + } else { + uint newSize = d->size + l.d->size; + const bool isTooSmall = newSize > d->alloc; + if (!isDetached() || isTooSmall) { + QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); + reallocData(d->size, isTooSmall ? newSize : d->alloc, opt); + } - if (d->alloc) { - T *w = d->begin() + newSize; - T *i = l.d->end(); - T *b = l.d->begin(); - while (i != b) { - if (QTypeInfo::isComplex) - new (--w) T(*--i); - else - *--w = *--i; + if (d->alloc) { + T *w = d->begin() + newSize; + T *i = l.d->end(); + T *b = l.d->begin(); + while (i != b) { + if (QTypeInfo::isComplex) + new (--w) T(*--i); + else + *--w = *--i; + } + d->size = newSize; } - d->size = newSize; } return *this; } -- cgit v1.2.3 From 0d0141d746e71f25fd68e1439f8251e4e476e332 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 29 Apr 2016 23:14:01 -0700 Subject: Don't bother asking if Linux supports a monotonic clock: it does Change-Id: Id5480807d25e49e78b79ffff144a0e61bd001dff Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Lars Knoll --- src/corelib/tools/qelapsedtimer_unix.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp index 1e672531c8..e1fc77fb4c 100644 --- a/src/corelib/tools/qelapsedtimer_unix.cpp +++ b/src/corelib/tools/qelapsedtimer_unix.cpp @@ -115,7 +115,11 @@ static inline void qt_clock_gettime(clockid_t clock, struct timespec *ts) static int unixCheckClockType() { -#if (_POSIX_MONOTONIC_CLOCK-0 == 0) && defined(_SC_MONOTONIC_CLOCK) +#ifdef Q_OS_LINUX + // Despite glibc claiming that we should check at runtime, the Linux kernel + // always supports the monotonic clock + return CLOCK_MONOTONIC; +#elif (_POSIX_MONOTONIC_CLOCK-0 == 0) && defined(_SC_MONOTONIC_CLOCK) // we need a value we can store in a clockid_t that isn't a valid clock // check if the valid ones are both non-negative or both non-positive # if CLOCK_MONOTONIC >= 0 && CLOCK_REALTIME >= 0 -- cgit v1.2.3 From ac7d14f1aa0c0efd861d9801540aaf4e940bb786 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 14:38:09 +0300 Subject: QDateTimeParser: enable RVO in format() Change-Id: I3d9f84d03519b2b8fb37c7d2e773e68bc4b9a1d3 Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetimeparser.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index c1abdf11a7..fbf91fe8a4 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1555,10 +1555,7 @@ QString QDateTimeParser::SectionNode::format() const qWarning("QDateTimeParser::sectionFormat Internal error 2"); return QString(); } - - QString str; - str.fill(fillChar, count); - return str; + return QString(count, fillChar); } -- cgit v1.2.3 From 6cbcff49716e8632fa5d41f68fc11e9ebaf1d3c6 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 12:02:31 +0300 Subject: QDateTime: use default ctor to create invalid object Don't perform some internal init functions. Change-Id: I9986e7a8adab35499aea804d1019012547aefd5d Reviewed-by: Marc Mutz Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 7cc86eb3f1..e18c220884 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -4699,7 +4699,7 @@ QDateTime QDateTime::fromString(const QString &string, const QString &format) Q_UNUSED(string); Q_UNUSED(format); #endif - return QDateTime(QDate(), QTime(-1, -1, -1)); + return QDateTime(); } #endif // QT_NO_DATESTRING -- cgit v1.2.3 From 5eae0ce8008ec4d8641ffdc5eeb221a3da0abfc9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 6 Jul 2015 12:27:01 +0200 Subject: QScoped(Array)Pointer: canonicalize swapping This includes: - have nothrow member-swap - have ADL non-member swap - not specialize qSwap or std::swap Also prevent QScopedPointer <-> QScopedArrayPointer swaps by overloading swap (both member and non-member) on QScopedArrayPointer. It's not 100% safe, but it's what we're doing elsewhere (QMulti(Map,Hash), say). That's technically a SiC change if users expected (qualified) std::swap to invoke QScopedPointer::swap(), but those users were doing it wrong to begin with, and they now get a compile-error instead of silent pessimization, because generic std::swap() doesn't work on QScopedPointer, due to lack of copy (and thus move) semantics. Change-Id: I3ab5c1668722a2c8ccafc16f57310ce8d4bffbd6 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qscopedpointer.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h index d98b914757..3e6af97a33 100644 --- a/src/corelib/tools/qscopedpointer.h +++ b/src/corelib/tools/qscopedpointer.h @@ -162,7 +162,7 @@ public: return oldD; } - inline void swap(QScopedPointer &other) + void swap(QScopedPointer &other) Q_DECL_NOTHROW { qSwap(d, other.d); } @@ -189,18 +189,9 @@ inline bool operator!=(const QScopedPointer &lhs, const QScopedPoint } template -Q_INLINE_TEMPLATE void qSwap(QScopedPointer &p1, QScopedPointer &p2) +inline void swap(QScopedPointer &p1, QScopedPointer &p2) Q_DECL_NOTHROW { p1.swap(p2); } -QT_END_NAMESPACE -namespace std { - template - Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QScopedPointer) &p1, QT_PREPEND_NAMESPACE(QScopedPointer) &p2) - { p1.swap(p2); } -} -QT_BEGIN_NAMESPACE - - namespace QtPrivate { template struct QScopedArrayEnsureSameType; @@ -230,6 +221,9 @@ public: return this->d[i]; } + void swap(QScopedArrayPointer &other) Q_DECL_NOTHROW // prevent QScopedPointer <->QScopedArrayPointer swaps + { QScopedPointer::swap(other); } + private: explicit inline QScopedArrayPointer(void *) { // Enforce the same type. @@ -245,6 +239,10 @@ private: Q_DISABLE_COPY(QScopedArrayPointer) }; +template +inline void swap(QScopedArrayPointer &lhs, QScopedArrayPointer &rhs) Q_DECL_NOTHROW +{ lhs.swap(rhs); } + QT_END_NAMESPACE #endif // QSCOPEDPOINTER_H -- cgit v1.2.3 From 0b2bc18efdd37e0cf00c40017c55a4f26cd4c60a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 1 May 2016 19:22:40 -0700 Subject: Mark QTimeZone constructor nothrow. Change-Id: Id5480807d25e49e78b79ffff144a9eead3fc9597 Reviewed-by: Marc Mutz --- src/corelib/tools/qtimezone.cpp | 2 +- src/corelib/tools/qtimezone.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp index 3c7417d64e..63a21ec75c 100644 --- a/src/corelib/tools/qtimezone.cpp +++ b/src/corelib/tools/qtimezone.cpp @@ -325,7 +325,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz); Create a null/invalid time zone instance. */ -QTimeZone::QTimeZone() +QTimeZone::QTimeZone() Q_DECL_NOTHROW : d(0) { } diff --git a/src/corelib/tools/qtimezone.h b/src/corelib/tools/qtimezone.h index b5957150f9..db99f07f44 100644 --- a/src/corelib/tools/qtimezone.h +++ b/src/corelib/tools/qtimezone.h @@ -74,7 +74,7 @@ public: }; typedef QVector OffsetDataList; - QTimeZone(); + QTimeZone() Q_DECL_NOTHROW; explicit QTimeZone(const QByteArray &ianaId); explicit QTimeZone(int offsetSeconds); /*implicit*/ QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name, -- cgit v1.2.3 From 04ca11e6f9c69ac47cca8a35135718cc67f5019c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 30 Apr 2016 20:11:35 -0700 Subject: Remove includes to qdatetime_p.h that aren't necessary Since I'm changing QDateTime's privates, it's easier to know what may be depending on it or not. Change-Id: Id5480807d25e49e78b79ffff144a53018d057e19 Reviewed-by: Marc Mutz --- src/corelib/tools/qlocale.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index eccedca4c8..ea5d74d9bb 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -54,7 +54,6 @@ #include "qlocale.h" #include "qlocale_p.h" #include "qlocale_tools_p.h" -#include "qdatetime_p.h" #include "qdatetimeparser_p.h" #include "qnamespace.h" #include "qdatetime.h" -- cgit v1.2.3 From 7abb90a70aed97c665430eb1e9f174dce26addd4 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 15:50:11 +0300 Subject: QDateTimeParser: proper construction of QString ... with known size and known char by corresponding ctor. Don't use fill() for this case. Change-Id: I475a0655132ecbb40b1eac919309597b2560e71b Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetimeparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index fbf91fe8a4..9b0f293d59 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -847,7 +847,7 @@ int QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionInde if (skipToNextSection(sectionIndex, currentValue, digitsStr)) { state = Acceptable; const int missingZeroes = sectionmaxsize - digitsStr.size(); - text.insert(index, QString().fill(QLatin1Char('0'), missingZeroes)); + text.insert(index, QString(missingZeroes, QLatin1Char('0'))); used = sectionmaxsize; cursorPosition += missingZeroes; ++(const_cast(this)->sectionNodes[sectionIndex].zeroesAdded); -- cgit v1.2.3 From c6618cb8852cd4572d42004c58c6b9c11affc635 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 14:36:32 +0300 Subject: QDateTimeParser: de-duplicate calls and cache results Change-Id: I0d6065fbdd19acff14072ff626585e8a12a3e073 Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetimeparser.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 9b0f293d59..5eaa1252d6 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -553,19 +553,20 @@ int QDateTimeParser::sectionSize(int sectionIndex) const // is the previous value and displayText() is the new value. // The size difference is always due to leading zeroes. int sizeAdjustment = 0; - if (displayText().size() != text.size()) { + const int displayTextSize = displayText().size(); + if (displayTextSize != text.size()) { // Any zeroes added before this section will affect our size. int preceedingZeroesAdded = 0; if (sectionNodes.size() > 1 && context == DateTimeEdit) { - for (QVector::ConstIterator sectionIt = sectionNodes.constBegin(); - sectionIt != sectionNodes.constBegin() + sectionIndex; ++sectionIt) { + const auto begin = sectionNodes.cbegin(); + const auto end = begin + sectionIndex; + for (auto sectionIt = begin; sectionIt != end; ++sectionIt) preceedingZeroesAdded += sectionIt->zeroesAdded; - } } sizeAdjustment = preceedingZeroesAdded; } - return displayText().size() + sizeAdjustment - sectionPos(sectionIndex) - separators.last().size(); + return displayTextSize + sizeAdjustment - sectionPos(sectionIndex) - separators.last().size(); } else { return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex) - separators.at(sectionIndex + 1).size(); @@ -1164,11 +1165,12 @@ end: if (newCurrentValue.daysTo(minimum) != 0) { break; } - toMin = newCurrentValue.time().msecsTo(minimum.time()); + const QTime time = newCurrentValue.time(); + toMin = time.msecsTo(minimum.time()); if (newCurrentValue.daysTo(maximum) > 0) { toMax = -1; // can't get to max } else { - toMax = newCurrentValue.time().msecsTo(maximum.time()); + toMax = time.msecsTo(maximum.time()); } } else { toMin = newCurrentValue.daysTo(minimum); -- cgit v1.2.3 From 361564dacf75019f8436ac42fa44c95ceac9e1db Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 29 Apr 2016 13:24:20 +0300 Subject: QDateTimeParser: adapt unquote() to make good use of QStringRef. Avoid unnecessary allocations. Change-Id: I9bed622c0dd7d9fe993b52d9169d1773957da4f2 Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz --- src/corelib/tools/qdatetimeparser.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 5eaa1252d6..8ddf1d9e41 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -313,7 +313,7 @@ int QDateTimeParser::sectionPos(const SectionNode &sn) const */ -static QString unquote(const QString &str) +static QString unquote(const QStringRef &str) { const QChar quote(QLatin1Char('\'')); const QChar slash(QLatin1Char('\\')); @@ -357,10 +357,8 @@ static inline int countRepeat(const QString &str, int index, int maxCount) static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote) { - QString str(string.mid(from, size)); - if (lastQuote >= from) - str = unquote(str); - list->append(str); + const QStringRef separator = string.midRef(from, size); + list->append(lastQuote >= from ? unquote(separator) : separator.toString()); } @@ -471,7 +469,7 @@ bool QDateTimeParser::parseFormat(const QString &newFormat) if (parserType != QVariant::Time) { const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4), 0 }; newSectionNodes.append(sn); - newSeparators.append(unquote(newFormat.mid(index, i - index))); + newSeparators.append(unquote(newFormat.midRef(index, i - index))); i += sn.count - 1; index = i + 1; newDisplay |= MonthSection; -- cgit v1.2.3